我有一个随时间变化的公司员工数据集,看起来像这样
data.table(firm = c(rep("A", 8), rep("B", 8)),
employee = c(1, 2, 3, 4, 1, 2, 3, NA, 5, 6, NA, NA, 5, 6, 7, 8),
year = c(rep(1, 4), rep(2, 4)))
firm employee_id year
A 1 1
A 2 1
A 3 1
A 4 1
A 1 2
A 2 2
A 3 2
A NA 2
B 5 1
B 6 1
B NA 1
B NA 1
B 5 2
B 6 2
B 7 2
B 8 2
我想计算每个公司的年度== 1的员工百分比= = 2 .
输出应该是这样的
firm year continued_employees
A 2 0.75
B 2 1
我可以在每年的循环中使用它
sum(employee_id[year==1] %in% employee_id[year==2]) / length(employee_id[year==1])
但我有大约4万家公司和10年的观察 . 有关如何在 dplyr
或 data.table
语法中执行此操作的任何想法?
3 回答
这是一个不那么漂亮的
data.table
方法,你可以用于任何数量的公司和年份:由于您的样本数据只有两年,因此您只能获得一个列表元素 .
加入转移年份
这是一种使用一种具有转移年份的自我联接的方法:
第一个表达式修改
DT
以表示继续雇员:使用shift()
或者,
shift()
函数可用于计算cont
列 . 聚合部分与上面的连接方法相同 .shift()
要求确保按年份排序数据 .基准
在撰写本文时,除了OP自己尝试使用循环之外,还提出了三种方法:
by docendo discimus
加入转移年份
使用
shift()
Jean Vuda的答案在基准测试中未被考虑,因为它仅限于2年 .
根据OP, 生产环境 数据集包括40 k公司和10年的数据 . 对于实际的基准测试,会创建一个类似大小的样本数据集:
样本数据集由4 M行组成,在从长格式转换为宽格式后可以最佳地显示:
399996:040000 6 2001 2002 NA 2004 2005 NA NA NA 2009 2010
399997:040000 7 NA 2002 NA NA 2005 2006 2007 2008 2009 2010
399998:040000 8 2001 2002 2003 NA NA NA 2007 NA NA 2010
399999:040000 9 2001 2002 2003 NA 2005 2006 2007 2008 NA
400000:040000 10 2001 2002 2003 NA NA 2006 2007 2008 2009 2010
对于基准测试,使用
microbenchmark
包是因为可以传递检查函数以验证结果是否相同:基准代码:
基准测试结果表明,连接方法比移位方法快4倍,比docendo discimus方法快8倍 .
这是一个稍微不同的方法: