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

Identify matched pairs and create a common key

我有

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

因此,id A 已与 FBECD[=25= 匹配]

我想为

这样的对创建一个 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 已与 F(第 1 行)的键 1 匹配,F 已与 A(第 1 行)匹配6) 还有键 1。 Common key不一定是数字,也可以是string或factor。

我如何完成此操作 1) 如果我的数据框包含 匹配对,2) 如果我的 DF 还包含观察结果 而没有 配对 3) 是否有 tidyverse 解决方案?

您可以使用一个临时变量来完成此操作,该变量按字母顺序粘贴 record_idmatched.with 中的字符串 (row-wise),然后按该变量分组并选择第一个 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(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

我们可以使用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

我们也可以使用

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