data.table中的"by"(分组) - 我错过了什么?

hhh*_*hhh 13 r data.table

我正在处理一个大的data.table并使用'by'来'分组'3个变量.

我的data.table是d并且具有键"ma"(10位整数但我在下面缩短了它).

但是设置by="ma,year,month"(对我来说,更直观的分组语句)并没有给出我想要的东西.例如,ma = 284有2011年11月的3个条目,或者ma = 672有2011年12月的2个条目.

> d[,list(n=length(trx_num)),by=list(ma,year,month)]
      ma year month n
  1: 284 2011    12 3
  2: 284 2012     1 1
  3: 284 2011    11 5
  4: 284 2011    11 1
  5: 284 2011    11 2
 ---
5782971: 672 2012     7 1
5782972: 672 2011    12 1
5782973: 672 2012     2 1
5782974: 672 2011    12 1
5782975: 672 2012     1 1
Run Code Online (Sandbox Code Playgroud)

但是,反转'by'顺序会产生所需的结果.

> d[,list(n=length(trx_num)),by=list(month,year,ma)]
     month year ma  n
  1:    12 2011 284  3
  2:     1 2012 284  1
  3:    11 2011 284  8
  4:     5 2012 543  7
  5:     7 2012 543  3
 ---
1214686:     5 2012 672 28
1214687:     4 2012 672 13
1214688:    12 2011 672 11
1214689:     7 2012 672  9
1214690:     9 2012 672 11
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么?提前致谢.

编辑:

str()给出错误结果的数据

> str(d)
Classes âdata.tableâ and 'data.frame':  14688135 obs. of  3 variables:
 $ ma   : num  3e+10 3e+10 3e+10 3e+10 3e+10 ...
 $ year : int  2011 2012 2011 2011 2011 2011 2011 2011 2011 2011 ...
 $ month: int  12 1 11 12 11 11 11 11 11 11 ...
 - attr(*, ".internal.selfref")=<externalptr>
 - attr(*, "sorted")= chr "ma"
Run Code Online (Sandbox Code Playgroud)

str()错误的结果:

> str(d[,.N,by=list(ma,year,month)])
Classes âdata.tableâ and 'data.frame':  5782975 obs. of  4 variables:
 $ ma   : num  3e+10 3e+10 3e+10 3e+10 3e+10 ...
 $ year : int  2011 2012 2011 2011 2011 2012 2012 2012 2012 2012 ...
 $ month: int  12 1 11 11 11 5 7 6 9 8 ...
 $ N    : int  3 1 5 1 2 1 1 1 1 1 ...
 - attr(*, ".internal.selfref")=<externalptr>
Run Code Online (Sandbox Code Playgroud)

和str()的正确结果:

> str(d[,.N,by=list(month,year,ma)])
Classes âdata.tableâ and 'data.frame':  1214690 obs. of  4 variables:
 $ month: int  12 1 11 5 7 6 9 8 11 12 ...
 $ year : int  2011 2012 2011 2012 2012 2012 2012 2012 2011 2011 ...
 $ ma   : num  3e+10 3e+10 3e+10 3e+10 3e+10 ...
 $ N    : int  3 1 8 7 3 12 15 3 6 6 ...
 - attr(*, ".internal.selfref")=<externalptr>
Run Code Online (Sandbox Code Playgroud)

Mat*_*wle 7

要结束注释跟踪,ma列是类型numeric和包含的值,它们完全不同但非常接近,几乎在机器容差范围内但不完全.换句话说,这种情况:

 x < y < z
 (y-x) just less than machine tolerance so considered equal
 (z-y) just less than machine tolerance so considered equal
 (z-x) just over machine tolerance so considered not equal
Run Code Online (Sandbox Code Playgroud)

当这样的列与另外两列(即by=3列)一起分组时,这3列的顺序(如果其中一列具有上述值)可以改变这些值是否被认为是相等的(并且在同一组中) .

解决方案不是为这些数据使用类型numeric(double另一个名称).使用integer,或者在这种情况下,整数大于2 ^ 31(导致强制double和精度损失,iiuc)character. data.table快速排序integercharacter.double无论如何,它的排序速度并不快.

我们将尝试添加一个新warningdata.table:

FR#2469添加新tolerance.warning选项以检测并发出warning是否有任何numeric值接近但不在机器容差范围内