3

我有两张大桌子。一个带有标识符(未排序),另一个带有标识符列表(包含第一个表中的所有标识符)以及一个变量的关联值。我想在我的第一个表中添加一列,其中包含第二个表中的关联值。是否有一种聪明的方法可以继续使用 R 的已实现功能?

IE

table 1
id
8979786
62782
6268768
6776566

table 2
id        var
1          5
2          2
3          NA
…
9999999    6

结果应该是

table1
id       var
8979786   5
62782     NA
6268768   7
4776566   4

提前致谢

4

3 回答 3

5

那么该id列在两个表中?你可以merge把它们放在一起:merge(table1, table2, sort = FALSE)。有许多可供探索的合并选项可让您模拟不同类型的连接,类似于 SQL 中的内、左、右和外连接。我在此处添加了附加参数sort,以保留 table1 的原始顺序。

如果表 1 中有 id 而表 2 中没有 id,并且您想为这些显示 NA,请添加all.x = TRUE为参数。这相当于左连接。all.y是右连接,all = TRUE相当于完全外连接。

可重现的例子:

> set.seed(1)
> table1 <- data.frame( id = sample(1:5, 5, FALSE))
> table1
  id
1  2
2  5
3  4
4  3
5  1
> table2 <- data.frame( id = 1:5, var = rnorm(5))
> table2
  id        var
1  1  1.2724293
2  2  0.4146414
3  3 -1.5399500
4  4 -0.9285670
5  5 -0.2947204
> merge(table1, table2, sort = FALSE)
  id        var
1  2  0.4146414
2  5 -0.2947204
3  4 -0.9285670
4  3 -1.5399500
5  1  1.2724293
于 2011-04-22T14:34:51.393 回答
3

这是一种 data.table 这样做的方式,以防数据很大并且速度是一个问题。有关详细信息,请参阅帮助页面?data.table

当 i 是 data.table 时,x(即外部 data.table)必须有一个键。i(即内部 data.table)使用键连接到 x,并返回 x 中匹配的行。在 i 中的每一列与 x 的键中的每一列之间执行等值连接。匹配是在 O(log n) 时间内编译的 C 中的二进制搜索。如果 i 的列数少于 x 的键,则 x 的许多行可能与 i 的每一行匹配。如果 i 的列多于 x 的键,则 i 未参与连接的列将包含在结果中。如果 i 也有一个键,则 i 的键列用于匹配 x 的键列,并
执行两个表的二进制合并。

请注意,我稍微调整了 Chase 提供的示例数据,以使某些关于匹配的点data.table更加明显:

require(data.table)
#Version 1.7.7
set.seed(1)
table1 <- data.table(id = sample(3:7, 5, FALSE), var1 = rnorm(5), key="id")
table2 <- data.table(id = 5:10, var2 = rnorm(6), key="id")

#Default: If id in table 1 is not in table 2, return NA
table2[table1]
#      id         var2       var1
# [1,]  3           NA -0.2947204
# [2,]  4           NA  1.2724293
# [3,]  5 -0.005767173 -0.9285670
# [4,]  6  2.404653389 -1.5399500
# [5,]  7  0.763593461  0.4146414

#If one wants to get rid of the NAs
table2[table1, nomatch=0]
#      id         var2       var1
# [1,]  5 -0.005767173 -0.9285670
# [2,]  6  2.404653389 -1.5399500
# [3,]  7  0.763593461  0.4146414

#Or the other way around: get all ids of table 2
table1[table2]
#      id       var1         var2
# [1,]  5 -0.9285670 -0.005767173
# [2,]  6 -1.5399500  2.404653389
# [3,]  7  0.4146414  0.763593461
# [4,]  8         NA -0.799009249
# [5,]  9         NA -1.147657009
# [6,] 10         NA -0.289461574

强制性速度测试:

set.seed(10)
df1 <- data.frame(id = sample(1:5e6, 5e6, FALSE))
df2 <- data.frame(id = sample(1:5e6, 5e6, FALSE), var = rnorm(5e6))
system.time(df_solution <- merge(df1, df2, sort = TRUE))
#    user  system elapsed 
#   33.10    0.32   33.54
merge_dt <- function(df1, df2) {
  dt1 <- setkey(as.data.table(df1), "id")
  dt2 <- setkey(as.data.table(df2), "id")
  return(dt1[dt2])
}
system.time(dt_solution <- merge_dt(df1, df2))
#    user  system elapsed 
#   12.94    0.01   12.95 
all.equal(df_solution, as.data.frame(dt_solution))
#[1] TRUE

还有我通常的免责声明:我还在学习很多关于这个包的知识,所以你可以在包主页上找到更好的信息。

于 2012-01-17T14:11:44.650 回答
2

我刚刚实现了一个解决这个问题的函数(合并两个 data.frame 对象,同时保持两个对象之一的顺序),您可以在此处查看其使用的代码和示例:

http://www.r-statistics.com/2012/01/merging-two-data-frame-objects-while-preserving-the-rows-order/

于 2012-01-15T11:22:11.247 回答