r-识别匹配的配对并创建一个公共密钥



我有

df<-data.frame(record_id=c("A", "B", "C", "D", "E", "F"), var1=1:6, matched.with=rev(c("A", "B", "C", "D", "E", "F")))
> df
record_id var1 matched.with
1         A    1            F
2         B    2            E
3         C    3            D
4         D    4            C
5         E    5            B
6         F    6            A

因此,idAF匹配,BE匹配,CD匹配

我想为这样的对创建一个common.key变量

df.common.key
record_id var1 matched.with common.key
1         A    1            F          1
2         B    2            E          2
3         C    3            D          3
4         D    4            C          3
5         E    5            B          2
6         F    6            A          1

这表明A已经与具有密钥1F(行1(匹配,并且F已经与具有同样密钥1A(行6(匹配。公共键不必是数字,也可以是字符串或因子。

我如何做到这一点1(如果我的数据帧只包括匹配对,2(我的DF也包括观察而没有匹配对3(有不同的解决方案吗?

我们可以使用pminpmax获得字母的唯一组合(按相同顺序(。然后,我们可以使用grp列来创建common.key

library(tidyverse)
df %>% 
group_by(grp = paste0(pmin(record_id, matched.with), pmax(record_id, matched.with))) %>% 
mutate(common.key = cur_group_id()) %>% 
select(-grp)

输出

grp   record_id  var1 matched.with common.key
<chr> <chr>     <int> <chr>             <int>
1 AF    A             1 F                     1
2 BE    B             2 E                     2
3 CD    C             3 D                     3
4 CD    D             4 C                     3
5 BE    E             5 B                     2
6 AF    F             6 A                     1

您可以使用一个临时变量来完成此操作,该变量按字母顺序(按行(粘贴record_idmatched.with中的字符串,然后按该变量分组并选择第一个var1放入common.key

df %>% 
rowwise() %>% 
mutate(common = paste0(sort(c(record_id, matched.with)), collapse = '')) %>% 
group_by(common) %>% 
mutate(common.key = first(var1)) %>% 
ungroup() %>% 
select(-common)
#> # A tibble: 6 x 4
#> record_id  var1 matched.with common.key
#>   <chr>     <int> <chr>             <int>
#> 1 A             1 F                     1
#> 2 B             2 E                     2
#> 3 C             3 D                     3
#> 4 D             4 C                     3
#> 5 E             5 B                     2
#> 6 F             6 A                     1

我们也可以使用

library(dplyr)
library(stringr)
df %>% 
group_by(grp = str_c(pmin(record_id, matched.with), 
pmax(record_id, matched.with))) %>% 
mutate(common.key = first(var1)) %>%
ungroup %>% 
select(-grp)

-输出

# A tibble: 6 × 4
record_id  var1 matched.with common.key
<chr>     <int> <chr>             <int>
1 A             1 F                     1
2 B             2 E                     2
3 C             3 D                     3
4 D             4 C                     3
5 E             5 B                     2
6 F             6 A                     1

使用联接:

library(tidyverse)
df %>%   
mutate(id = pmin(matched.with, record_id)) %>% 
left_join(select(df, record_id, var1), by = c("id" = "record_id")) %>% 
select(record_id, var1 = var1.x, matched.with, common.key = var1.y)
# A tibble: 6 x 4
record_id  var1 matched.with common.key
<chr>     <int> <chr>             <int>
1 A             1 F                     1
2 B             2 E                     2
3 C             3 D                     3
4 D             4 C                     3
5 E             5 B                     2
6 F             6 A                     1

最新更新