如何从r中的两个数据框中选择匹配的行

Posted

技术标签:

【中文标题】如何从r中的两个数据框中选择匹配的行【英文标题】:How to select matching rows from two data frames in 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

【问题讨论】:

【参考方案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。我需要一个特殊的库来运行你的代码吗?

以上是关于如何从r中的两个数据框中选择匹配的行的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 selectInput 从 R 中的数据框中选择特定列?

如何从R中的数据框中删除重复的行[重复]

如何从数据框中选择一些具有特定行名的行? [关闭]

如何根据条件选择R数据框中的连续行?

Pandas:如何根据特定列上特定值的条件选择数据框中的行[重复]

如何使用 pyspark 2.1.0 选择另一个数据框中不存在的行?