我有
df <- data.frame(id = c(c(letters[1:4]), c(LETTERS[5:8])),
group = c(rep("same", length = 4), rep("opp", length = 4)),
match = c("H", "G", "E", "F", "c", "d", "b", "a"))
其中每个 id(行)与列表中的另一个 id 唯一配对。希望找到 tidyverse 解决方案来创建一个指示符列,使用分配给每对的序列号来显示唯一的配对。所以结果将是
的输出df <- data.frame(pair = c(1,2,3,4,3,4,2,1), id = c(c(letters[1:4]), c(LETTERS[5:8])),
group = c(rep("same", length = 4), rep("opp", length = 4)),
match = c("H", "G", "E", "F", "c", "d", "b", "a"))
可能有更优雅的方法,但您可以通过两个
mutate
步骤实现所需的输出 - 第一个创建临时分组变量 (tmp
),稍后使用 select
删除该变量,另一个使用 cur_group_id
根据 tmp
分配组编号:
df %>%
mutate(tmp = ifelse(group %in% "same", paste0(id, match), paste0(match, id))) %>%
mutate(pair = cur_group_id(), .by = tmp) %>% select(-tmp)
输出
id group match pair
1 a same H 1
2 b same G 2
3 c same E 3
4 d same F 4
5 E opp c 3
6 F opp d 4
7 G opp b 2
8 H opp a 1
如果是一对一的关系
df%>% group_by(pair = pmin(id, match))%>% 变异(对= cur_group_id())
# A tibble: 8 × 4
# Groups: pair [4]
id group match pair
<chr> <chr> <chr> <int>
1 a same H 1
2 b same G 2
3 c same E 3
4 d same F 4
5 E opp c 3
6 F opp d 4
7 G opp b 2
8 H opp a 1
或
mutate(df, pair = match(pmin(id, match), id))
在基础 R 中:
transform(df, pair = match(pmin(id,match), id))
id group match pair
1 a same H 1
2 b same G 2
3 c same E 3
4 d same F 4
5 E opp c 3
6 F opp d 4
7 G opp b 2
8 H opp a 1
如果是一对多关系:
df %>%
group_by(pair= paste(pmin(id, match), pmax(id, match)))%>%
mutate(pair =cur_group_id())
# A tibble: 8 × 4
# Groups: pair [4]
id group match pair
<chr> <chr> <chr> <int>
1 a same H 1
2 b same G 2
3 c same E 3
4 d same F 4
5 E opp c 3
6 F opp d 4
7 G opp b 2
8 H opp a 1
library(tidyverse)
df |>
group_by(pair = map2_chr(id, match, ~ str_flatten(sort(c(.x, .y))))) |>
mutate(pair = cur_group_id()) |>
ungroup()