【问题标题】:unexpected outcome of data.table fintersect all = TRUEdata.table 的意外结果 fintersect all = TRUE
【发布时间】:2021-12-20 03:06:14
【问题描述】:

数据表的设置操作

惊人的 data.table 包包含Set operations for data tables。文档中给出的示例包含只有一列的数据表。为了了解它们的行为和与基本 R 集操作的区别,我用另一列扩展了表。这导致了一个意想不到的结果,这可能是由于我的理解,如果stackoverflow社区同意,我也会提出一个错误。

示例 1,具有预期结果

以下示例显示了当我们将参数all 的默认设置设置为FALSE 时的预期行为

library(data.table)

(DT <- 
    data.table(
      x = c(1, 2, 2, 2),
      y = LETTERS[c(1, 2, 2, 3)]
    )
) 
   x y
1: 1 A
2: 2 B
3: 2 B
4: 2 C
data.table::fintersect(DT, DT, all = FALSE)  
   x y
1: 1 A
2: 2 B
3: 2 C

示例 2,结果出乎意料

以下示例显示了当我们不使用参数all 的默认设置而是将其设置为TRUE 时的意外行为

library(data.table)

(DT <- 
    data.table(
      x = c(1, 2, 2, 2),
      y = LETTERS[c(1, 2, 2, 3)]
    )
) 
   x y
1: 1 A
2: 2 B
3: 2 B
4: 2 C
data.table::fintersect(DT, DT, all = TRUE)  
   x y
1: 1 A
2: 2 B
3: 2 B

预期结果

   x y
1: 1 A
2: 2 B
3: 2 B
4: 2 C

分析

data.table::fintersect 的实现可以在 Git 上找到,由 commit of jangorecki committed on 6 Mar 2016 找到

在 R 代码中重现这个函数给出了预期的结果

DT1 <-  copy(DT)[, ".seqn" := rowidv(DT)]
DT2 <-  copy(DT)[, ".seqn" := rowidv(DT)]
DT1[DT2, .SD, .SDcols=setdiff(names(DT1),".seqn"), nomatch=0L, on=names(DT1)]
   x y
1: 1 A
2: 2 B
3: 2 B
4: 2 C

问题

由于此功能存在多年,如果这是一个错误,我会感到惊讶,可能我的理解是错误的。这可能是由于我的 R 版本或其他依赖项(请参阅下面的 sessionInfo()) 应该是什么行为?

会话信息

R version 4.0.5 (2021-03-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19043)

Matrix products: default

locale:
[1] LC_COLLATE=Dutch_Netherlands.1252  LC_CTYPE=Dutch_Netherlands.1252    LC_MONETARY=Dutch_Netherlands.1252
[4] LC_NUMERIC=C                       LC_TIME=Dutch_Netherlands.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] data.table_1.14.2

loaded via a namespace (and not attached):
 [1] compiler_4.0.5  fastmap_1.1.0   htmltools_0.5.2 tools_4.0.5     yaml_2.2.1      rmarkdown_2.10  knitr_1.33      xfun_0.25      
 [9] digest_0.6.27   rlang_0.4.11    evaluate_0.14  

【问题讨论】:

  • 您应该在问题跟踪器上报告为错误。这与命名冲突有关。该函数使用xy 作为data.tables 的名称。您还碰巧有名为xy 的列。因此,在函数x[, ".seqn" := rowid(x)] 中,在您的示例中,data.table 在向量上使用rowid(x),而不是整个data.table。如果您将向量更改为x1y1(或在您的工作示例中将您的数据表名称更改为DT1),它可以工作。维护者的一个潜在解决方案是将xy 的名称更改为.x.y 或其他方式以降低可能性。
  • 非常感谢 Cole,我提出了 bug

标签: r data.table set


【解决方案1】:

示例 3,具有预期结果且 ALL = TRUE

Cole的回答确实是根本原因,非常感谢。我会提出一个错误。

下面是基于 cmets 的工作示例

library(data.table)

(DT <- 
    data.table(
      x1 = c(1, 2, 2, 2),
      y1 = LETTERS[c(1, 2, 2, 3)]
    )
) 

   x1 y1
1:  1  A
2:  2  B
3:  2  B
4:  2  C

data.table::fintersect(DT, DT, all = TRUE)  

   x1 y1
1:  1  A
2:  2  B
3:  2  B
4:  2  C

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 2011-09-15
    • 2012-04-02
    • 2019-05-14
    • 2017-07-11
    • 2011-04-17
    相关资源
    最近更新 更多