Другая возможность tidyverse
может быть:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(n() > 1) paste(name, letters[1:length(name)], sep = "_") else name)
id name unique_name
<chr> <chr> <chr>
1 172262 Fam Fam_a
2 172262 Fam Fam_b
3 172262 Fam Fam_c
4 172262 CM_fam CM_fam
5 172504 CBT_Fam CBT_Fam_a
6 172504 CBT_Fam CBT_Fam_b
7 172504 CBT_Fam CBT_Fam_c
8 172507 TAU TAU
9 172507 CBT_Educ CBT_Educ
10 172507 CBT_MI CBT_MI
Во-первых, она группируется по "id" и "name".Затем, если число наблюдений в группе больше 1, оно объединяет значение из «имени» с последовательностью букв длины «имя», в противном случае присваивает значение из «имени».
Или используя length()
вместо n()
:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(length(name) > 1) paste(name, letters[1:length(name)], sep = "_") else name)
Или с seq_along()
вместо n()
:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(any(seq_along(name) != 1)) paste(name, letters[1:length(name)], sep = "_") else name)
Или немного другой подход с использованием gl()
длягенерация букв:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(n() > 1) paste(name, gl(length(name), 1, n(), letters), sep = "_") else name)
id name unique_name
<chr> <chr> <chr>
1 172262 Fam Fam_a
2 172262 Fam Fam_b
3 172262 Fam Fam_c
4 172262 CM_fam CM_fam
5 172504 CBT_Fam CBT_Fam_a
6 172504 CBT_Fam CBT_Fam_b
7 172504 CBT_Fam CBT_Fam_c
8 172507 TAU TAU
9 172507 CBT_Educ CBT_Educ
10 172507 CBT_MI CBT_MI
или:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(length(name) > 1) paste(name, gl(length(name), 1, n(), letters), sep = "_") else name)
или:
dat %>%
group_by(id, name) %>%
mutate(unique_name = if(any(seq_along(name) != 1)) paste(name, gl(length(name), 1, n(), letters), sep = "_") else name)