【问题标题】:How to select matching rows from two data frames in r如何从r中的两个数据框中选择匹配的行
【发布时间】:2019-08-06 01:55:30
【问题描述】:
> df1
     n1 mt1
1  Mike  48
2  John  64
3 Steve  32
4   Dan  87

> df2
       n1 mt1
1   Peter  32
2   Chris  23
3 Brendan  44
4  Joseph  52

我想从 df1 和 df2 中选择第 1 行。 df1 和 df2 的第 2 行。 df1 和 df2 的第 3 行。 df1 和 df2 的第 4 行。我可以用下面的代码做到这一点,但想知道当有数百行时是否有更简单的方法来做到这一点?我总是从两个 df 中寻找匹配的行,并希望它们配对。

> m1 <- rbind(df1[1,], df2[1,])
> m2 <- rbind(df1[2,], df2[2,])
> m3 <- rbind(df1[3,], df2[3,])
> m4 <- rbind(df1[4,], df2[4,])

> m1
     n1 mt1
1  Mike  48
2 Peter  32

> m2
      n1 mt1
2   John  64
21 Chris  23

> m3
        n1 mt1
3    Steve  32
31 Brendan  44

> m4
       n1 mt1
4     Dan  87
41 Joseph  52

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以使用基础 R 中的 Map 并为 df1df2 子集和 rbind 创建一系列行索引。但是,请确保 df1df2 的行数相同,否则您可能会得到一些意想不到的结果。

    Map(function(x, y) rbind(df1[x, ], df2[x, ]), 1:nrow(df1), 1:nrow(df2))
    
    #[[1]]
    #      n1 mt1
    #1   Mike  48
    #11 Peter  32
    
    #[[2]]
    #      n1 mt1
    #2   John  64
    #21 Chris  23
    
    #[[3]]
    #        n1 mt1
    #3    Steve  32
    #31 Brendan  44
    
    #[[4]]
    #       n1 mt1
    #4     Dan  87
    #41 Joseph  52
    

    我们也可以将每一行 split 放入数据帧列表中,然后 rbind

    Map(rbind, split(df1, 1:nrow(df1)), split(df2, 1:nrow(df2)))
    

    purrr 的版本是

    purrr::map2(split(df1, 1:nrow(df1)), split(df2, 1:nrow(df2)), rbind)
    

    由于行数相同,我们也可以使用lapply

    lapply(1:nrow(df1), function(x) rbind(df1[x, ], df2[x, ]))
    

    【讨论】:

    • 谢谢!所有 3 个版本都运行良好,是否有偏好选择哪一个?
    • @mrsama 实际上,它们都或多或少地做同样的事情,因此您可以选择其中任何一个。我仍然更喜欢第一个Map 解决方案,因为它对我来说更清楚。
    【解决方案2】:

    使用split

    df=rbind(df1,df2)
    split(df,rep((seq.int(nrow(df1))),2)) # or split(df,c(seq.int(nrow(df1)),seq.int(nrow(df2))))
    $`1`
          n1 mt1
    1   Mike  48
    11 Peter  32
    
    $`2`
          n1 mt1
    2   John  64
    21 Chris  23
    
    $`3`
            n1 mt1
    3    Steve  32
    31 Brendan  44
    
    $`4`
           n1 mt1
    4     Dan  87
    41 Joseph  52
    

    【讨论】:

      【解决方案3】:

      另一种直观的方法是使用 for 循环

      df1 <- data.frame(n1=c('Mike','John','Steve','Dan'),
                        mt1=c(48,64,32,87), stringsAsFactors = F)
      df2 <- data.frame(n1=c('Peter','Chris','Brendan','Joseph'),
                        mt1=c(32,23,44,52), stringsAsFactors = F)
      for (i in 1:nrow(df1)) {
        assign(paste0("m", i), rbind(df1[i, ], df2[i, ]))
      }
      

      这将创建几个新的数据帧——在本例中为 m1、m2、m3 和 m4——每个数据帧都有来自 df1 和 df2 的对应行。

      【讨论】:

      • 谢谢,但这对我不起作用。 "paste0(m, i) 中的 m 有什么作用?
      • 抱歉,应该是“m”。创建新数据框的名称只是一个字符串字符。例如,它将创建名为 m1、m2、m3 等的数据帧。错误已修复。
      • 我希望这是否可行,但是当我运行它时它给了我 NULL?
      • 这很奇怪,因为它对我有用。我已经包含了完整的代码。尝试复制粘贴,看看是否有效。成功运行后,您的工作环境中应该有四个新的数据帧,分别命名为 m1、m2、m3 和 m4。
      • 我复制并粘贴了您编辑的文本,但运行它时仍然得到 NULL。我需要一个特殊的库来运行你的代码吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多