当使用`by`子句时,S3方法在data.table中调度

时间:2015-10-16 18:13:28

标签: r data.table

更新:看来这是data.table版本1.9.4的问题,而不是该软件包的最新版本(撰写本文时为1.9.6)。

我有一张表,我通过fread读到了这样的表格:

library(data.table)
library(bit64)
dt = fread('"x","y"\n2489751247,"a"\n2492940518,"b"\n2444706811,"a"\n2408767228,"b"')

:>              x y
:>  1: 2489751247 a
:>  2: 2492940518 b
:>  3: 2444706811 a
:>  4: 2408767228 b

我希望x的总和以y为条件,但data.table给出了错误的答案:

dt[,.(total=sum(x)),by=y]

:>     y         total
:>  1: a 2.437946e-314
:>  2: b 2.421765e-314
没有警告信息的礼貌。事实证明x是class integer:

lapply(dt,class)

:>  $x
:>  [1] "integer64"
:>  $y
:>  [1] "character"

所以我可以手动执行s3调度:

dt[,.(total=sum.integer64(x)),by=y]

:>     y      total
:>  1: a 4934458058
:>  2: b 4901707746

由于某些原因在j子句中使用x的类导致data.table给出 正确答案:

dt[,.(total=sum(x),cls=class(x)),by=y]

:>     y      total       cls
:>  1: a 4934458058 integer64
:>  2: b 4901707746 integer64

这很奇怪。有没有办法告诉data.table在没有明确使用类的情况下使用S3方法?

2 个答案:

答案 0 :(得分:4)

此特定问题特定于data.table版本1.9.4,而不是data.table包的最新版本(截至本文撰写时为1.9.6)。您可以通过以下方式检查您的data.table版本。

installed.packages()['data.table','Version']

如果它小于1.9.6,则需要致电install.packages('data.table')。请注意,如果您使用Revolution Analytics提供的R版本,则需要将repos段明确设置为your favorite CRAN mirror作为其最新的回购(截至撰写本文时)有data.table版本1.9.4:

install.packages('data.table',repos="http://my.favorite.CRAN.mirror/")

虽然我很少使用.Rprofile.site,但我将这些行放在我使用的计算机上的该文件中:

if( packageVersion("data.table") == package_version('1.9.4'))
    install.packages("data.table",lib=Sys.getenv("R_LIBS_USER"),repos='http://my.favorite.CRAN.mirror')

答案 1 :(得分:0)

对于其他使用较新版本的data.table搜索此文件的人,请注意,在使用by时,S3方法分派仍然不总是发生-显然出于速度考虑,这是故意的。参见https://github.com/Rdatatable/data.table/issues/3533