我有一个大的data.table
,大约有40列,我需要添加一条记录,其中我只有40列中的3列(其余的只是NA
)。为了制作一个可重复的例子:
require(data.table)
data(iris)
setDT(iris)
# this works (and is the expected result):
rbind(iris, list(6, NA, NA, NA, "test"))
问题是我有37个以上的空列(我要输入的数据位于变量的第1列,第2列和第37列)。所以,我需要rep
一些NA
。但如果我尝试:
rbind(iris, list(6, rep(NA, 3), "test"))
它不起作用(尺寸不同)。我能做到
rbind(iris, list(c(6, rep(NA, 3), "test")))
但它(显然)将整个第一列强制为char。我已经尝试将列表取消列出,反转list(c(
序列(它只接受列表),还没有找到任何内容。
请注意,这不是关于rbind data.tables的(几个)帖子的重复,因为我能够做到这一点。我无法做到的是使用rep(NA, x)
进行和时维护正确的数据类。
答案 0 :(得分:3)
你可以......
rbind(data.table(iris), c(list(6), logical(3), list("test")))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1: 5.1 3.5 1.4 0.2 setosa
2: 4.9 3.0 1.4 0.2 setosa
3: 4.7 3.2 1.3 0.2 setosa
4: 4.6 3.1 1.5 0.2 setosa
5: 5.0 3.6 1.4 0.2 setosa
---
147: 6.3 2.5 5.0 1.9 virginica
148: 6.5 3.0 5.2 2.0 virginica
149: 6.2 3.4 5.4 2.3 virginica
150: 5.9 3.0 5.1 1.8 virginica
151: 6.0 NA NA NA test
logical(n)
与rep(NA, n)
相同。我将iris
包裹在data.table()
中,因此使用了rbindlist
代替rbind.data.frame
,而"test"
被视为新的因素级别而非无效级别。
我认为还有更好的方法,比如......
newrow = setDT(iris[NA_integer_, ])
newrow[, `:=`(Sepal.Length = 6, Species = factor("test")) ]
rbind(data.table(iris), newrow)
# or
rbind(data.table(iris), list(Sepal.Length = 6, Species = "test"), fill=TRUE)
这些方法更清晰,不需要摆弄列数。
我更喜欢newrow
方式,因为它会留下一个表格,我可以检查以查看数据转换。
答案 1 :(得分:2)
我们可以使用replicate
rbind(iris, c(6, replicate(3, NA, simplify = FALSE), "test"))
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1: 5.1 3.5 1.4 0.2 setosa
# 2: 4.9 3.0 1.4 0.2 setosa
# 3: 4.7 3.2 1.3 0.2 setosa
# 4: 4.6 3.1 1.5 0.2 setosa
# 5: 5.0 3.6 1.4 0.2 setosa
# ---
#147: 6.3 2.5 5.0 1.9 virginica
#148: 6.5 3.0 5.2 2.0 virginica
#149: 6.2 3.4 5.4 2.3 virginica
#150: 5.9 3.0 5.1 1.8 virginica
#151: 6.0 NA NA NA test
或者@Frank发表评论
rbind(iris, c(6, as.list(rep(NA, 3)), "test"))