最有效的方法来计算data.table中的组总数?

时间:2014-11-03 21:11:24

标签: r data.table

如果您有一个设置了某些键的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))有效,但可能效率不高。有更快的方法吗?

2 个答案:

答案 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