我有
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
因此,idA
与F
匹配,B
与E
匹配,C
与D
匹配
我想为这样的对创建一个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
已经与具有密钥1
的F
(行1(匹配,并且F
已经与具有同样密钥1
的A
(行6(匹配。公共键不必是数字,也可以是字符串或因子。
我如何做到这一点1(如果我的数据帧只包括匹配对,2(我的DF也包括观察而没有匹配对3(有不同的解决方案吗?
我们可以使用pmin
和pmax
获得字母的唯一组合(按相同顺序(。然后,我们可以使用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_id
和matched.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