关于r:基于公共列合并数据帧但保留x中的所有行

merge dataframes based on common columns but keeping all rows from x

本问题已经有最佳答案,请猛点这里访问。

我需要合并两个数据帧x和y,它们有大约50个共同的列和一些独特的列,并且我需要保留x的所有行。

如果我跑步,它会起作用:

1
 NewDataframe <- merge(x, y, by=c("ColumnA","ColumnB","ColumnC"),all.x=TRUE)

问题是有50多个公共列,我宁愿避免键入所有公共列的名称。

我尝试过:

1
 NewDataframe <- merge(x, y, all.x=TRUE)

但出现以下错误:

1
2
 Error in merge.data.table(x, y, all.x = TRUE) :
 Elements listed in `by` must be valid column names in x and y

是否有任何方法可以将by与公共列一起使用,而不键入所有列,而是将所有行保留在x之外?

谢谢您。


您希望基于所有公用列进行合并。因此,首先需要找出两个数据帧之间哪些列名称是通用的。

1
common_col_names <- intersect(names(x), names(y))

然后在合并函数中使用这个字符向量作为by参数。

1
merge(x, y, by=common_col_names, all.x=TRUE)

编辑:在阅读了@andrew gustar的答案之后,我再次检查了合并函数的文档,这正是默认的by参数:

1
2
3
4
5
## S3 method for class 'data.frame'
merge(x, y, by = intersect(names(x), names(y)), # <-- Look here
      by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,
      sort = TRUE, suffixes = c(".x",".y"),
      incomparables = NULL, ...)

我认为您有数据表而不是简单的数据帧,合并在这两者之间的工作方式略有不同。您可以尝试通过使用NewDataframe <- merge.data.frame(x, y, all.x=TRUE)强制它使用数据帧方法,默认情况下,该方法应合并所有共享列名称。


dplyrleft_join函数应该给您想要的东西。

首先创建一些虚拟数据…

1
2
3
4
shared <- tibble(a=rnorm(327), b=rnorm(327),c=rnorm(327),d=rnorm(327),e=rnorm(327),f=rnorm(327),g=rnorm(327))
x <- cbind(shared, tibble(v =rnorm(327),w=rnorm(327),x=rnorm(327),y=rnorm(327),z=rnorm(327)))
y <- cbind(shared, tibble(h =rnorm(327),i=rnorm(327),j=rnorm(327),k=rnorm(327),l=rnorm(327)))
rm(shared)

然后运行连接…

1
2
dplyr::left_join(x,y)
# Joining, by = c("a","b","c","d","e","f","g")

如您所见,函数计算出两个列之间共享的列,并在联接中自动使用它们。