带有 all=True 的 merge.data.table 引入了 NA 行。它是不是正确?
Posted
技术标签:
【中文标题】带有 all=True 的 merge.data.table 引入了 NA 行。它是不是正确?【英文标题】:merge.data.table with all=True introduces NA row. Is this correct?带有 all=True 的 merge.data.table 引入了 NA 行。它是否正确? 【发布时间】:2013-03-12 01:38:03 【问题描述】:在填充的 data.table 和另一个空的 data.table 之间进行合并会在结果 data.table 中引入一个 NA 行:
a = data.table(c=c(1,2),key='c')
b = data.table(c=3,key='c')
b=b[c!=3]
b
# Empty data.table (0 rows) of 1 col: c
merge(a,b,all=T)
# c
# 1: NA
# 2: 1
# 3: 2
为什么?我希望它只返回 data.table a
的行,就像它对 merge.data.frame 所做的那样:
> merge.data.frame(a,b,all=T,by='c')
# c
#1 1
#2 2
【问题讨论】:
所以你想合并a
和一个空的数据表b
。为什么你以这种不寻常的方式介绍b
?为什么不使用b=data.table()
?
@user974514:我只是想重现问题,因为它出现在我的代码中。通常,我的代码中的data.table
已填充,但有时不会填充,在我的情况下,表是键控的,合并自然会使用这些键。一个简单的data.table()
并不能完全重现我遇到的问题。
@user974514,这将给出一个 NULL data.table(0 行和列)并且不会有“key”列。所以,合并是不可能的。
@Arun,我不这么认为。我对data.frame
做了同样的事情,结果是预期的结果:一个新的data.frame
,只有填充的行。
【参考方案1】:
问题中的示例过于简单,无法显示问题,因此造成了混乱和讨论。使用两个单列 data.table
s 不足以显示 merge
的作用!
这是一个更好的例子:
> a = data.table(P=1:2,Q=3:4,key='P')
> b = data.table(P=2:3,R=5:6,key='P')
> a
P Q
1: 1 3
2: 2 4
> b
P R
1: 2 5
2: 3 6
> merge(a,b) # correct
P Q R
1: 2 4 5
> merge(a,b,all=TRUE) # correct.
P Q R
1: 1 3 NA
2: 2 4 5
3: 3 NA 6
> merge(a,b[0],all=TRUE) # incorrect result when y is empty, agreed
P Q R
1: NA NA NA
2: NA NA NA
3: 1 3 NA
4: 2 4 NA
> merge.data.frame(a,b[0],all=TRUE) # correct
P Q R
1 1 3 NA
2 2 4 NA
Ricardo 对此进行了深入研究,并在 v1.8.9 中对其进行了修复。来自新闻:
当 y 为空并且 all.y=TRUE(或 all=TRUE),#2633。谢谢 给 Vinicius Almendra 报告。已添加测试。
【讨论】:
【参考方案2】:所有:逻辑; all = TRUE 是保存设置 all.x = TRUE 和 all.y = TRUE 的简写。
all.x:逻辑;如果为 TRUE,那么额外的行将被添加到输出中,每一行对应一个 x 在 y 中没有匹配的行。这些行将在这些列中包含“NA” 通常用来自 y 的值填充。默认为 FALSE,因此只有行 来自 x 和 y 的数据都包含在输出中。
all.y:逻辑;类似于上面的 all.x。
这取自 data.table documentation。有关更多信息,请查看那里的 merge
函数的参数描述。
我认为这回答了你的问题。
【讨论】:
也许你可以试试ifelse(dim(b)[1]==0, merge(a,b,all.x=T), merge(a,b,all.y=T))
或类似的东西
本文档与merge.data.frame
相同,但行为不同。我不明白为什么带有空表的完全外连接应该添加一个 NA 行。【参考方案3】:
假设您以自己的方式定义了a
和b
。 rbind(a,b)
的简单用法将只返回 a
的行。
但是,如果您想将 NULL 数据表 b
与其他一些非空数据表 a
合并,则有不同的方法。当我不得不在不同的循环中合并不同的数据表时,我遇到了类似的问题。我使用了这个解决方法。
#some loop that returns data.table named a
#another loop starts
if(all.equal(a,b<-data.table())==TRUE)
b<-a
next
merge(a,b,c("Factor1","Factor2"))
这对我有帮助,也许对你也有帮助。
【讨论】:
对不起,我不太明白你的 if 语句。如果a
是维度0 by 0
的data.table
(如b
),则将b
分配给a
。为什么?而且您没有使用copy(a)
。这将只是通过引用分配,而不是将 a 复制到 b。我不明白。
假设您有一个循环来填充 data.table a
。所以它不是空的。但在循环结束时,您希望将其与其他数据表 b
合并,该表在第一次迭代中可以为空,但在第二次迭代中变为非空。这就是此解决方法要解决的问题。
投反对票来自我,如果您能解释(或编辑),我很乐意投赞成票)。
感谢您的回复。现在说得通了。但它没有回答 OP 的问题,因为 data.table 不是 0 行和列,但只有 0 行和 1 列.
对于OP的问题,我推荐使用rbind(a,b)
。正如 OP 要求的那样,输出将只有 a
行。【参考方案4】:
这是意料之中的,因为merge.data.frame
all=T
是full outer join
,所以你得到两个表的所有键见about merge
【讨论】:
表b
有一个空键(无行),与值为 NA 的键不同。
您可能发现了一个错误,因为这是一个非常不寻常的情况,您可以在数据表列表中发布吗?
谢谢。我刚刚提交了它和我发现的另一个错误,也与空 data.table 的...
table b not 有一个空键。 tables()
表示键设置为列c
。
不知道为什么我们还在谈论它,data.table
应该复制 data.frame 行为,这是一个错误,让我们关闭广告继续...以上是关于带有 all=True 的 merge.data.table 引入了 NA 行。它是不是正确?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 all() 为空的可迭代对象返回 True? [复制]
如何用 NA 以外的值填充 merge(..., all = TRUE, ...) 中的缺失值?
如何使用 facet 和 margin=TRUE 更改 ggplot 中的 strip.text 标签
为啥 Python 内置的“all”函数为空的可迭代对象返回 True?