更有效地将匹配列与data.table中的重复项合并

Mic*_*ico 10 merge r data.table

我有两个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
Run Code Online (Sandbox Code Playgroud)

我只想添加numy; 因为num匹配1-1 let,所以重复是不重要的.

这是一种有效的方法; 我感觉有一些更简单的东西.

setkey(x, let)
setkey(y, let)

y <- x[!duplicated(let), c("let", "num"), with = FALSE][y]
Run Code Online (Sandbox Code Playgroud)

Dav*_*urg 7

我能想到的唯一改进是

  1. 你可以跳过这个setkey(x, let)部分

  2. 您也可以y通过引用更新(而不是使用<-然后再分配创建副本y)

如果您使用的是当前稳定版本data.table(v <= 1.9.4),则必须使用allow.cartesian = TRUE

setkey(y,let)
y[x[!duplicated(let)], num := i.num, allow.cartesian = TRUE][]
Run Code Online (Sandbox Code Playgroud)

您也可以使用unique而不是duplicated(它们都有data.table方法)

y[unique(x, by = "let"), num := i.num, allow.cartesian = TRUE]
Run Code Online (Sandbox Code Playgroud)

这是使用新.EACHI方法的另一种可能性,尽管这里不需要使用by=.EACHI.我已经向您展示了为您公开此功能.看一下这篇文章,详细解释它的作用以及何时有用.

y[x, num := unique(i.num), by = .EACHI, allow.cartesian = TRUE]
Run Code Online (Sandbox Code Playgroud)

编辑 :(感谢@Arun指出这一点)

我们不应该allow.cartesian在这里需要论证,因为没有重复i.事实上,这是一个错误,#742已在当前的开发版本(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]
Run Code Online (Sandbox Code Playgroud)