【问题标题】:How to merge 2 columns on 1 column如何在 1 列上合并 2 列
【发布时间】:2015-04-24 23:17:40
【问题描述】:

我想合并 2 个 df,其中 df1 包含 2 列和 df2 1 列,在这种情况下如何应用函数合并?

这里是样例:

df1 <- data.frame(var1=letters[1:5],var2=letters[6:10])
df2 <- data.frame(var3=letters[1:10])

错误尝试:

merge(df1,df2,by.x=c("var1","var2"),by.y="var3",all.y=TRUE)

如何合并这两个 df,以便匹配搜索使用 df1 (var1 & var2) 的两列并在 df2 (var3) 上进行操作?

期望的输出:

    var1  var2   var3 
1     a    f       a
2     b    g       b
3     c    h       c
4     d    i       d
5     e    j       e
6     <NA> <NA>    f
7     <NA> <NA>    g
8     <NA> <NA>    h
9     <NA> <NA>    i 
10    <NA> <NA>    j

编辑:改进的数据(我希望):

df1 <- data.frame(var1=c(letters[1:5],rep("x",5)),var2=c(letters[6:10],rep("x",5)))
df2 <- data.frame(var3=letters[1:10])

期望的输出:

     var1  var2   var3 
 1     a    f       a
 2     b    g       b
 3     c    h       c
 4     d    i       d
 5     e    j       e
 6     x    x       f
 7     x    x       g
 8     x    x       h
 9     x    x       i 
10     x    x       j

【问题讨论】:

  • merge 两次可能是一种可能的解决方案。
  • 是的,我想过,但可能会与我的真实数据混淆。
  • 凌乱,我的意思是弄乱数据 :) 我认为,这可能很容易出错
  • 您能否澄清“以便匹配搜索使用 df1 (var1 & var2) 的两列”?在您想要的输出中,看起来 var1 与 var3 匹配;除了包含在结果表中之外,var2 是否在连接中发挥作用?

标签: r dataframe


【解决方案1】:

您可以将merge 与参数by='row.names'sort=F 一起使用(正如Matthew Plourde 所指出的那样),以免merge 弄乱顺序:

> merge(df1, df2, by='row.names', sort=FALSE, all=TRUE)[c("var1", "var2", "var3")]
   var1 var2 var3
1     a    f    a
2     b    g    b
3     c    h    c
4     d    i    d
5     e    j    e
6  <NA> <NA>    i
7  <NA> <NA>    f
8  <NA> <NA>    g
9  <NA> <NA>    h
10 <NA> <NA>    j

【讨论】:

  • 永远不会想到by=0。给merge sort=FALSE 参数可以让你一路走好。
  • 你真的应该澄清这是加入行名。
【解决方案2】:

根据第一个期望的输出,这是一个可能的data.table 解决方案

library(data.table)
setkey(setDT(df2), var3)
df2[df1, `:=`(var1 = i.var1, var2 = i.var2)][]
#     var3 var1 var2
#  1:    a    a    f
#  2:    b    b    g
#  3:    c    c    h
#  4:    d    d    i
#  5:    e    e    j
#  6:    f   NA   NA
#  7:    g   NA   NA
#  8:    h   NA   NA
#  9:    i   NA   NA
# 10:    j   NA   NA

【讨论】:

  • 看来@user1981275 想出了一个更通用的解决方案
  • 是的,这很创新。从未想过by=0(可能以前见过,不过不记得了)
  • 接受的答案是加入行名。虽然很有趣,而且对我来说也是新的,但我会犹豫将其称为通用解决方案。
【解决方案3】:

你真的只需要根据df1cbind 他们重新排序df2

cbind(df1, df2[order(match(df2$var3, df1$var1)),, drop=FALSE])

如果df2 有多于一列,则不需要drop=FALSE

#    var1 var2 var3
# 1     a    f    a
# 2     b    g    b
# 3     c    h    c
# 4     d    i    d
# 5     e    j    e
# 6     x    x    f
# 7     x    x    g
# 8     x    x    h
# 9     x    x    i
# 10    x    x    j

保持这种方法,对于没有 xs 的第一个数据集,您可以使用:

cbind(lapply(df1, `length<-`, nrow(df2)), df2[order(match(df2$var3, df1$var1)),, drop=FALSE])

#    var1 var2 var3
# 1     a    f    a
# 2     b    g    b
# 3     c    h    c
# 4     d    i    d
# 5     e    j    e
# 6  <NA> <NA>    f
# 7  <NA> <NA>    g
# 8  <NA> <NA>    h
# 9  <NA> <NA>    i
# 10 <NA> <NA>    j

或者以更易读的方式:

df1 <- lapply(df1, `length<-`, nrow(df2))
df2 <- df2[order(match(df2$var3, df1$var1)),, drop=FALSE]
cbind(df1, df2)

【讨论】:

  • 对于第二个数据集(带有“x”),为什么不只是cbind(df1, df2)
  • 假设df2 已经有序,这是 OP 样本数据的属性,但我想一般不是他的真实数据的属性。
猜你喜欢
  • 1970-01-01
  • 2021-04-20
  • 2013-12-14
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多