我有两个data.table
,两个共享一个变量;我正在尝试添加一个在第二个中缺失的变量,但该变量与共享变量一对一地绑定。
这显然是一个合并,但由于共享变量有多个实例,我不得不使用感觉变通方法来合并新变量。
让我们具体一点。
x <- data.table(let = rep(letters[1:3], 2:4),
num = rep(1:3, 2:4), other = rnorm(9))
y <- data.table(let = rep(c("a", "c"), c(10, 6)))
x:
let num other
1: a 1 -0.41695882
2: a 1 -0.59875888
3: b 2 -0.19433915
4: b 2 0.58406046
5: b 2 -0.33922321
6: c 3 -0.63076561
7: c 3 1.06987710
8: c 3 0.08869372
9: c 3 -1.31196123
y:
let
1: a
2: a
3: a
4: a
5: a
6: a
7: a
8: a
9: a
10: a
11: c
12: c
13: c
14: c
15: c
16: c
我只想将num
列添加到y
;由于num
与let
匹配为1-1,因此重复项并不重要。
这是一种有效的方法;我感觉有一些更简单的东西。
setkey(x, let)
setkey(y, let)
y <- x[!duplicated(let), c("let", "num"), with = FALSE][y]
答案 0 :(得分:7)
我能想到的唯一改进是
您可以跳过setkey(x, let)
部分
您还可以通过引用更新y
(而不是使用<-
创建副本,然后分配回y
)
如果您使用的是当前稳定版本的data.table
(v <= 1.9.4),则必须使用allow.cartesian = TRUE
setkey(y,let)
y[x[!duplicated(let)], num := i.num, allow.cartesian = TRUE][]
您也可以使用unique
代替duplicated
(他们都有data.table
方法)
y[unique(x, by = "let"), num := i.num, allow.cartesian = TRUE]
这是使用新.EACHI
方法的另一种可能性,尽管此处不需要使用by=.EACHI
。我已经向您展示了为您公开此功能。请查看this post以获取有关此功能以及何时有用的详细说明。
y[x, num := unique(i.num), by = .EACHI, allow.cartesian = TRUE]
编辑 :(感谢@Arun指出这一点)
我们不应该在这里需要allow.cartesian
参数,因为i
中没有重复项。实际上,it's a bug, #742已经修复了current development version (1.9.5)。所以你只需要这样做:
y[x[!duplicated(let)], num := i.num]
# or
y[unique(x, by = "let"), num := i.num]
# or (though not recommended in this specific case)
y[x, num := unique(i.num), by = .EACHI]
答案 1 :(得分:2)
好吧,我会使用类似下面的merge
,但我不确定它是否比你已经完成的更简单。
merge(y,unique(x[,c('let','num'), with=FALSE]), all.x=TRUE, by='let')
答案 2 :(得分:2)
同意@David,很难简化。但是下面几个关键点: - )
setkey(x,let)
y<-x[!duplicated(let),.(let,num)][y]