我有以下两个数据框:
> df1
# A tibble: 4 x 4
x y z w
<dbl> <dbl> <dbl> <dbl>
4 5 8 9
4 6 7 4
3 6 7 10
8 2 8 9
> df2
# A tibble: 4 x 4
x y z w
<dbl> <dbl> <dbl> <dbl>
6 2 7 9
2 6 7 10
4 5 8 12
4 5 8 3
我想发现df2中哪些行在df1中匹配,其中匹配意味着在至少n / 2列中相同.
所以在这个例子中,df2中的第1行与df1中的第4行匹配(第1列和第3列),df2中的第2行与第2列和第3列的df1中的第2行以及第2,3,4列中的第3行相匹配上.
我还必须保存重复行的位置以及它们匹配的列.
对于小数据集,我可以复制两个数据集并减去它们并计算零.然而,我需要的是一个可以在非常大的数据集(~20K行)上工作的解决方案.
有任何想法吗? dplyr解决方案(而不是data.table)将受到高度赞赏.
最佳答案 最终输出可能不是理想的格式,但它至少应该包含您正在寻找的信息,并且可以使用更多的字段/列.
df1 <- read.table(text =
"x y z w
4 5 8 9
4 6 7 4
3 6 7 10
8 2 8 9",
header = T)
df2 <- read.table(text =
"x y z w
6 2 7 9
2 6 7 10
4 5 8 12
4 5 8 3",
header = T)
library(dplyr)
library(tidyr)
为每个数据框添加行ID号,并使用gather将数据从wide更改为long. (我假设每行可以被视为唯一ID):
df1 <- df1 %>%
mutate(df1_id = row_number()) %>%
gather(field, value, x:w) %>%
arrange(df1_id)
df2 <- df2 %>%
mutate(df2_id = row_number()) %>%
gather(field, value, x:w) %>%
arrange(df2_id)
使用字段/列和值上的inner_join加入两个数据框.然后使用group和filter来仅获取具有两个或多个匹配项的字段和值组合
df2 %>%
inner_join(df1, by = c('value', 'field')) %>%
group_by(df2_id, df1_id) %>%
filter(n()>=2) %>% # where 2 is the minimum number of matches
arrange(df2_id, df1_id, value) %>%
select(df2_id, df1_id, field, value)
# A tibble: 13 x 4
# Groups: df2_id, df1_id [5]
df2_id df1_id field value
<int> <int> <chr> <int>
1 1 4 y 2
2 1 4 w 9
3 2 2 y 6
4 2 2 z 7
5 2 3 y 6
6 2 3 z 7
7 2 3 w 10
8 3 1 x 4
9 3 1 y 5
10 3 1 z 8
11 4 1 x 4
12 4 1 y 5
13 4 1 z 8
你可以看到df2 row id 1匹配字段y和w上的df1 row 4,
df2第2行匹配字段y和z上的df1第2行,
df2第2行也匹配字段y,x和w上的df1第3行.
df2行3和4匹配x,y和z上的df1行1.
安排和选择实际上只是更容易查看数据的必要条件.