【问题标题】:do.call rbind of data.table depends on location of NAdata.table 的 do.call rbind 取决于 NA 的位置
【发布时间】:2013-08-30 18:35:29
【问题描述】:

考虑一下

do.call(rbind, list(data.table(x=1, b='x'),data.table(x=1, b=NA)))

返回

   x  b
1: 1  x
2: 1 NA

但是

do.call(rbind, list(data.table(x=1, b=NA),data.table(x=1, b='x')))

返回

   x  b
1: 1 NA
2: 1 NA

如何在不重新排序列表内容的情况下强制执行第一个行为?

数据表在 mapreduce 作业中确实更快(在 55 个节点上调用 data.table ~10*3MM 次,数据表比数据帧快很多倍,所以我希望它能够工作......) 问候 萨塔什

【问题讨论】:

  • 我猜这是因为NA 是合乎逻辑的而as.logical('x')=NA,所以当rbind 决定该列是合乎逻辑的(基于它的第一个参数)时,它会强制后续项目匹配. do.call(rbind, list(data.table(x=1, b=as(NA,'character')),data.table(x=1, b='x'))) 工作...
  • 顺便说一下,data.tables 有一个“优化的do.call(rbind,...)”,叫做rbindlist。这个网站上有一些关于它的问题,例如,stackoverflow.com/questions/15673550/…
  • @Frank -- 非常有帮助的 cmets。我在答案中添加了对 rbindlist 的引用。

标签: r data.table rbind do.call


【解决方案1】:

正如 Frank 所指出的,问题在于(有些不可见)有几种不同类型的 NA。在命令行中键入NA 时生成的类是"logical",但也有NA_integer_、NA_real_、NA_character_ 和NA_complex_。

在您的第一个示例中,初始data.table 将列b 的类设置为“字符”,然后将第二个data.table 中的NA 强制转换为NA_character_。但是,在第二个示例中,第一个 data.table 中的 NA 将列 b 的类设置为“逻辑”,并且,当第二个 data.table 中的同一列被强制为“逻辑”时,它是转换为逻辑 NA。 (试试as.logical("x") 看看为什么。)

这一切都相当复杂(至少要表达清楚),但有一个相当简单的解决方案。只需创建一个 1 行模板 data.table,并将其添加到您想要添加到 rbind() 的每个 data.table 列表之前。无论data.table 在传递给rbind() 的列表中跟随它,它都会将每一列的类建立为您想要的,并且一旦其他所有内容绑定在一起,就可以将其修剪掉。

library(data.table)    

## The two lists of data.tables from the OP
A <- list(data.table(x=1, b='x'),data.table(x=1, b=NA))
B <- list(data.table(x=1, b=NA),data.table(x=1, b='x'))

## A 1-row template, used to set the column types (and then removed)
DT <- data.table(x=numeric(1), b=character(1))

## Test it out
do.call(rbind, c(list(DT), A))[-1,]
#    x  b
# 1: 1  x
# 2: 1 NA
do.call(rbind, c(list(DT), B))[-1,]
#    x  b
# 1: 1 NA
# 2: 1  x

## Finally, as _also_ noted by Frank, rbindlist will likely be more efficient
rbindlist(c(list(DT), B)[-1,]

【讨论】:

  • 当然,这可能会在所有情况下都会减慢rbinding 的速度。另一方面,向rbindlist() 添加第二个“colClasses”参数可能并不难,允许用户传入类名的字符向量或包含所需类元素的列表。
猜你喜欢
  • 1970-01-01
  • 2016-09-24
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-03
  • 1970-01-01
相关资源
最近更新 更多