【问题标题】:Operator == inconsistent in logical columns in data.table运算符 == 在 data.table 中的逻辑列中不一致
【发布时间】:2023-04-06 18:35:01
【问题描述】:

请参阅以下可重现的示例:

library(data.table)
set.seed(123)
DT <- data.table(A=rep(0.3,10000))
DT[, B := runif(.N) < A]
DT[B == T, .N]
# [1] 3005
DT[, summary(B)]
#    Mode   FALSE    TRUE    NA's
# logical    6995    3005       0

一切看起来都很好,两种方法的“TRUE”值的计数相同。现在用一个新的替换col B。

DT[, B := runif(.N) < A]
DT[B == T, .N]
# [1] 3331
DT[, summary(B)]
#    Mode   FALSE    TRUE    NA's
# logical    6981    3019       0 

B列中'T'的计数不同!!!它是同一列,但一种方法给出 3331 个“TRUE”值,另一个给出 3019 个值。

当 == 被绕过时

DT[B != F, .N]
# [1] 3019
DT[, summary(B)]
#    Mode   FALSE    TRUE    NA's
# logical    6981    3019       0 

这又是对的

我可以在 Windows 8.1 x64 上使用 data.table v1.94 和 1.9.5 重现它。


这是一个没有runif() 的更容易重现的示例。

require(data.table) ## 1.9.4+
DT = data.table(x = 1:5)
DT[, y := x <= 2L]
#    x     y
# 1: 1  TRUE
# 2: 2  TRUE
# 3: 3 FALSE
# 4: 4 FALSE
# 5: 5 FALSE

DT[y == TRUE, .N]
# [1] 2             <~~~~~~ correct result.

DT[, y := x <= 3L]
#    x     y
# 1: 1  TRUE
# 2: 2  TRUE
# 3: 3  TRUE
# 4: 4 FALSE
# 5: 5 FALSE

DT[y == TRUE, .N]
# [1] 2             <~~~~~~ incorrect result, should be 3!

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    现已在 GitHub 上的 v1.9.5 中修复。

    :=set* 现在删除辅助键(v1.9.4 中的新功能),以便 DT[x==y]:=set* 之后再次工作,而无需 options(datatable.auto.index=FALSE)。只有setkey() 正确删除了辅助键。添加了 23 项测试。感谢 user36312 的报告,#885

    【讨论】:

      【解决方案2】:

      看看@nrussell 的建议。 根据@Eddi 的说法,这也可能是一个错误。 下面可能是一个临时的解决方法。 @Arun 也建议。 请参考cmets的兑换。

      案例一

      > set.seed(123)
      > DT <- data.table(A=rep(0.3,10000))
      > DT[, B := runif(.N) < A]
      > DT[B == T, .N]
      [1] 3012
      > DT[, summary(B)]
         Mode   FALSE    TRUE    NA's 
      logical    6988    3012       0 
      

      案例2

      > set.seed(123)
      > DT[, B := runif(.N) < A]
      > DT[B == T, .N]
      [1] 3012
      > DT[, summary(B)]
         Mode   FALSE    TRUE    NA's 
      logical    6988    3012       0 
      

      案例3

      > set.seed(123)
      > DT[, B := runif(.N) < A]
      > DT[B != F, .N]
      [1] 3012
      > DT[, summary(B)]
         Mode   FALSE    TRUE    NA's 
      logical    6988    3012       0 
      

      【讨论】:

      • 这不是答案
      • 感谢您的回答@KFB。您的示例有效但是我不明白为什么当我不设置种子 DT[B == T, .N] 和 DT[, summary(B)] 在创建 col B 后会给出不同的结果。我的示例在每个 runif 之前没有 set.seed 是否运行良好?
      • @eddi,当然你的评论是可以理解的。尽管如此,我相信有时绿色用户(包括我自己)更容易“看到”案例场景以更好地理解。因此插图。谢谢
      • @KFB 一种解决方法是禁用索引,例如做DT[(B == T), .N]
      • 是的,错误 - 抱歉。 options(datatable.auto.index=FALSE) 关闭新功能。 := 需要删除所有涉及更新列的二级索引...
      猜你喜欢
      • 2017-03-17
      • 2022-01-20
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      相关资源
      最近更新 更多