rbindlist 两个 data.tables,其中一个具有因子,另一个具有列的字符类型

标签 r data.table

我刚刚在我的脚本中发现这个警告有点奇怪。

# Warning message:
# In rbindlist(list(DT.1, DT.2)) : NAs introduced by coercion

观察 1:这是一个可重现的示例:
require(data.table)
DT.1 <- data.table(x = letters[1:5], y = 6:10)
DT.2 <- data.table(x = LETTERS[1:5], y = 11:15)

# works fine
rbindlist(list(DT.1, DT.2))
#     x  y
#  1: a  6
#  2: b  7
#  3: c  8
#  4: d  9
#  5: e 10
#  6: A 11
#  7: B 12
#  8: C 13
#  9: D 14
# 10: E 15

但是,现在如果我转换列 xfactor (已订购或未订购)并执行相同操作:
DT.1[, x := factor(x)]
rbindlist(list(DT.1, DT.2))
#      x  y
#  1:  a  6
#  2:  b  7
#  3:  c  8
#  4:  d  9
#  5:  e 10
#  6: NA 11
#  7: NA 12
#  8: NA 13
#  9: NA 14
# 10: NA 15
# Warning message:
# In rbindlist(list(DT.1, DT.2)) : NAs introduced by coercion

但是rbind这项工作做得很好!
rbind(DT.1, DT.2) # where DT.1 has column x as factor
# do.call(rbind, list(DT.1, DT.2)) # also works fine
#     x  y
#  1: a  6
#  2: b  7
#  3: c  8
#  4: d  9
#  5: e 10
#  6: A 11
#  7: B 12
#  8: C 13
#  9: D 14
# 10: E 15

如果列 x 可以重现相同的行为是 ordered factor以及。自帮助页?rbindlist说:Same as do.call("rbind",l), but much faster. ,我猜这不是想要的行为?

这是我的 session 信息:
# R version 3.0.0 (2013-04-03)
# Platform: x86_64-apple-darwin10.8.0 (64-bit)
# 
# locale:
# [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
# 
# attached base packages:
# [1] stats     graphics  grDevices utils     datasets  methods   base     
# 
# other attached packages:
# [1] data.table_1.8.8
# 
# loaded via a namespace (and not attached):
# [1] tools_3.0.0

编辑:

观察 2:遵循@AnandaMahto 的另一个有趣的观察,颠倒顺序:
# column x in DT.1 is still a factor
rbindlist(list(DT.2, DT.1))
#     x  y
#  1: A 11
#  2: B 12
#  3: C 13
#  4: D 14
#  5: E 15
#  6: 1  6
#  7: 2  7
#  8: 3  8
#  9: 4  9
# 10: 5 10

这里,来自 DT.1 的专栏被默默逼到numeric .
编辑:澄清一下,这与 rbind(DT2, DT1) 的行为相同DT1 的列 x 是一个因素。 rbind似乎保留了第一个参数的类。我将把这部分留在这里,并提到在这种情况下,这是自 rbindlist 以来所需的行为。是 rbind 的更快实现.

观察3:如果现在,两列都转换为因子:
# DT.1 column x is already a factor
DT.2[, x := factor(x)]
rbindlist(list(DT.1, DT.2))
#     x  y
#  1: a  6
#  2: b  7
#  3: c  8
#  4: d  9
#  5: e 10
#  6: a 11
#  7: b 12
#  8: c 13
#  9: d 14
# 10: e 15

在这里,专栏x来自 DT.2丢失(/替换为 DT.1 )。如果顺序颠倒,则会发生完全相反的情况(DT.1 的 x 列被替换为 DT.2 的列)。

总的来说,处理factor好像有问题rbindlist 中的列.

最佳答案

更新 - 此错误 ( #2650 ) 已于 2013 年 5 月 17 日在 v1.8.9 中修复

我相信rbindlist当应用于因子时,将组合因子的数值并仅使用与第一个列表元素关联的级别。

在这个错误报告中:
http://r-forge.r-project.org/tracker/index.php?func=detail&aid=2650&group_id=240&atid=975

# Temporary workaround: 

levs <- c(as.character(DT.1$x), as.character(DT.2$x))

DT.1[, x := factor(x, levels=levs)]
DT.2[, x := factor(x, levels=levs)]

rbindlist(list(DT.1, DT.2))

作为对正在发生的事情的另一种看法:
DT3 <- data.table(x=c("1st", "2nd"), y=1:2)
DT4 <- copy(DT3)

DT3[, x := factor(x, levels=x)]
DT4[, x := factor(x, levels=x, labels=rev(x))]

DT3
DT4

# Have a look at the difference:
rbindlist(list(DT3, DT4))$x
# [1] 1st 2nd 1st 2nd
# Levels: 1st 2nd

do.call(rbind, list(DT3, DT4))$x
# [1] 1st 2nd 2nd 1st
# Levels: 1st 2nd

根据评论编辑:

至于观察 1,发生的事情类似于:
x <- factor(LETTERS[1:5])

x[6:10] <- letters[1:5]
x

# Notice however, if you are assigning a value that is already present
x[11] <- "S"  # warning, since `S` is not one of the levels of x
x[12] <- "D"  # all good, since `D` *is* one of the levels of x

关于rbindlist 两个 data.tables,其中一个具有因子,另一个具有列的字符类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15933846/

相关文章:

r - 连接数据框的行

r - 图像纹理 GLCM (mean_Envi)

使用带有行名和列名的 fread 读取文件

从 data.table 返回一个列表

r - 根据动态依赖的两个条件过滤

r - 当 x 轴离散时,R 中的水平线

arrays - R 中长度不同的数组的数组

r - ggplot2 将变量映射到 y 并使用 stat ="bin"时出错

r - 如何将列表分配为数据表中的观察值?

r - 如何选择所有列以及附加表达式