【问题标题】:How to match pairs and merge data frame by values in two columns?如何匹配对并按两列中的值合并数据框?
【发布时间】:2018-10-16 14:43:33
【问题描述】:
假设我有一个数据框
x y val
A B 5
A C 3
B A 7
B C 9
C A 1
如您所见,x 和 y 有两对匹配:
第 1 对:A B 5 和 B A 7
第 2 对:A C 3 和 C A 1
我想将它们合并到 A B 12 和 A C 4 并留下 B C 9,因为它没有一对 (C B)。
最终的数据框应如下所示:
x y val
A B 12
A C 4
B C 9
如何在 R 中实现这一点?
【问题讨论】:
标签:
r
dataframe
merge
match
【解决方案1】:
这是dplyr 的一种解决方案:
library(dplyr)
df %>%
mutate(var = paste(pmin(x, y), pmax(x, y))) %>%
group_by(var) %>%
summarise(val = sum(val))
# A tibble: 3 x 2
var val
<chr> <int>
1 A B 12
2 A C 4
3 B C 9
如果您希望 Melissa Key 提到 x 和 y 列,请将 separate(var, c("x", "y")) 添加到链的末尾。
【解决方案2】:
首先确保x 和y 是给DF_c 的字符,然后对它们进行排序给DF_s。最后执行聚合。不使用任何包。如果 x 和 y 已经是字符,则不需要第一行。
DF_c <- transform(DF, x = as.character(x), y = as.character(y))
DF_s <- transform(DF_c, x = pmin(x, y), y = pmax(x, y))
aggregate(val ~ x + y, DF_s, sum)
给予:
x y val
1 A B 12
2 A C 4
3 B C 9
【解决方案3】:
可以按row_number() 到sort 分组,并按排序顺序组合列以创建一个独立于顺序的pair。
注意:下面的解决方案也可以演变为适用于超过 2 列的配对。例如,将A B C、A C B 或B C A 视为同一组。
library(dplyr)
library(tidyr)
df %>%
group_by(row_number()) %>%
mutate(xy = paste0(sort(c(x,y)),collapse=",")) %>%
group_by(xy) %>%
summarise(val = sum(val)) %>%
separate(xy, c("x","y"))
## A tibble: 3 x 3
# x y val
#* <chr> <chr> <int>
#1 A B 12
#2 A C 4
#3 B C 9
数据:
df <- read.table(text =
"x y val
A B 5
A C 3
B A 7
B C 9
C A 1",
header = TRUE, stringsAsFactors = FALSE)