【问题标题】:Assignment by reference with sum() in data.table() yields incorrect result在 data.table() 中使用 sum() 引用赋值会产生不正确的结果
【发布时间】:2012-12-01 04:49:48
【问题描述】:

我有一个包含 3 列的 data.table 测试:Year、ID、Count(请参阅下面的前 3 列)。我想添加第四列来汇总 ID 和年份,如下所示:

setkey(test, Year, ID)
test[, annualCount := sum(Count), by=list(Year, ID)]

我得到的东西看起来很奇怪:似乎函数 [ 自动将 1 添加到我的年度计数。例如,ID 210 和 Y1 应该给我 8 而不是 9。

是data.table的bug吗?

    Year       ID    Count  annualCount
 1:   Y1      210        1            9
 2:   Y1      210        1            9
 3:   Y1      210        0            9
 4:   Y1      210        1            9
 5:   Y1      210        1            9
 6:   Y1      210        1            9
 7:   Y1      210        1            9
 8:   Y1      210        1            9
 9:   Y1      210        1            9
10:   Y1     3197        1            6
11:   Y1     3197        1            6
12:   Y1     3197        0            6
13:   Y1     3197        1            6
14:   Y1     3197        1            6
15:   Y1     3197        1            6    

更新:我使用的是 R 版本 2.15.0 (2012-03-30),但我安装了 data.table_1.8.6。当我安装这个包时,我收到一个警告,这个版本是在 2.15.1 上构建的。这是错误的原因吗?

更新 2:我安装了最新的 R(此时为 2.15.2),但没有帮助。使用相同的数据集, 如果我打电话

  test1 <- test[, list(annualCount = sum(Count)), by=list(Year, ID)]

然后我得到正确的结果。但如果我打电话

test2 <- test[, list(annualCount = sum(Count, na.remove = T)), by=list(Year, ID)]

然后 [ 自动将 1 添加到我的总和中。不幸的是,我无法从头开始复制带有此错误的数据集。

更新 3:dput(test) 输出。

structure(list(Year = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Y1", "Y2", "Y3"), class = "factor"), 
               ID = c(210, 210, 210, 210, 210, 210, 210, 210, 210, 
                            3197, 3197, 3197, 3197, 3197, 3197), 
               Count = c(1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)), 
          .Names = c("Year","ID", "Count"), class = c("data.table", "data.frame"), 
          row.names = c(NA, -15L), .internal.selfref = <pointer: 0x7fb6dc000778>)

谢谢。

【问题讨论】:

  • 对我来说没有错误,我用你的数据得到 8 和 5!
  • 感谢 agstudy。我更新了我的问题。顺便说一句,当我尝试另一个模拟数据集时,我无法复制这个错误。我在拉我的头发
  • :-) 我正在尝试安装最新的 R 以查看它是否可以解决我的问题
  • 我也得到了正确答案。清除您的工作区并重试?
  • 什么是na.remove?我认为正确的论点是na.rm?

标签: r data.table


【解决方案1】:

这不是data.table 的问题,而是人为错误;)

为了复制,这里有一些示例数据。我已经包含了一些NA 值来查看sum 函数的结果,无论是否带有删除NAs 的参数,即na.rm,而不是na.remove

set.seed(1)
test <- data.table(Year = rep("Y1", 15),
                   ID = c(rep(210, 9), rep(3197, 6)),
                   Count = sample(c(0, 1, NA), 15, 
                                  prob=c(.2, .65, .15), 
                                  replace=TRUE),
                   key = "Year,ID")
test
#     Year   ID Count
#  1:   Y1  210     1
#  2:   Y1  210     1
#  3:   Y1  210     1
#  4:   Y1  210    NA
#  5:   Y1  210     1
#  6:   Y1  210    NA
#  7:   Y1  210    NA
#  8:   Y1  210     0
#  9:   Y1  210     1
# 10:   Y1 3197     1
# 11:   Y1 3197     1
# 12:   Y1 3197     1
# 13:   Y1 3197     0
# 14:   Y1 3197     1
# 15:   Y1 3197     0

在我们创建新列之前,让我们进行一些聚合,看看sum 的不同选项会发生什么。

test[, list(annualCount = sum(Count)), by = key(test)]
#    Year   ID annualCount
# 1:   Y1  210          NA
# 2:   Y1 3197           4
test[, list(annualCount = sum(Count, na.rm = TRUE)), by = key(test)]
#    Year   ID annualCount
# 1:   Y1  210           5
# 2:   Y1 3197           4

现在,创建您的新列,并获得您预期的结果。

test[, annualCount := sum(Count, na.rm = TRUE), by = key(test)][]
#     Year   ID Count annualCount
#  1:   Y1  210     1           5
#  2:   Y1  210     1           5
#  3:   Y1  210     1           5
#  4:   Y1  210    NA           5
#  5:   Y1  210     1           5
#  6:   Y1  210    NA           5
#  7:   Y1  210    NA           5
#  8:   Y1  210     0           5
#  9:   Y1  210     1           5
# 10:   Y1 3197     1           4
# 11:   Y1 3197     1           4
# 12:   Y1 3197     1           4
# 13:   Y1 3197     0           4
# 14:   Y1 3197     1           4
# 15:   Y1 3197     0           4

【讨论】:

  • 再次感谢。我意识到 sum(1, na.remove = T) 产生 2。这是因为 R 假设 na.remove 是一个值为 T 的新逻辑变量,并在输入 SUM 函数时将其强制为 1。
  • @AdamNYC,我认为还有一两个包可以定义na.remove,所以这个错误是可以理解的:)
猜你喜欢
  • 1970-01-01
  • 2020-12-14
  • 2015-10-12
  • 2015-01-06
  • 1970-01-01
  • 2014-09-21
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
相关资源
最近更新 更多