如果您有一个设置了某些键的data.table dt
,那么如何最有效地计算组的总数?
> dt = data.table(a=c(1, 2, 2), b=c(1, 1, 2))
> dt
a b
1: 1 1
2: 2 1
3: 2 2
> setkey(dt, a)
> nrow(unique(dt))
2
上述解决方案nrow(unique(dt))
有效,但可能效率不高。有更快的方法吗?
答案 0 :(得分:1)
让我先描述一下sum(!duplicated(dt))
更快的原因:
当您使用nrow(unique(dt))
时,您需要先制作unique(dt)
表,但要制作此表,您需要先计算!duplicated(dt)
。
使用sum(!duplicated(dt))
时,无需制作unique(dt)
。 (你在这里节省一些时间!)
但这些还不是最快的方法。
这是一种更快捷的方法。只使用您认为关键的列:
> system.time((for (i in 1:1000) uk = nrow(unique(dt))))
user system elapsed
3.09 0.00 3.11
> system.time((for (i in 1:1000) uk = sum(!duplicated(dt))))
user system elapsed
0.63 0.00 0.63
> system.time((for (i in 1:1000) uk = sum(!duplicated(dt$a))))
user system elapsed
0.24 0.00 0.24
如果您有多个列作为键,则使用sum(!duplicated(dt))
会更容易。但是仍然可以将所有键列与paste
函数组合在一起来制作长键而不是所有键列。
请注意,我的data.table比您在分析中使用的要宽得多,因此速度更加明显。
答案 1 :(得分:0)
根据Mahdi Jadaliha的评论,我在数据上比较了两个解决方案。尺寸为11811 * 10,有4个按键和2284个唯一按键组合。有些不足为奇,sum(!duplicated(dt))
比nrow(unique(dt))
略高效。
> system.time((for (i in 1:10000) uk = nrow(unique(dt))))
user system elapsed
38.037 0.728 38.707
> system.time((for (i in 1:10000) uk = sum(!duplicated(dt))))
user system elapsed
29.154 0.723 29.872
> dim(dt)
[1] 11811 10
> length(key(dt))
[1] 4
> uk
[1] 2284