R 从id组中的非唯一名称创建唯一名称
在id中,我的数据有多个非唯一的名称标签。我想创建第三列,这样非唯一名称的末尾就可以粘贴一个字母来创建唯一的名称R 从id组中的非唯一名称创建唯一名称,r,dplyr,R,Dplyr,在id中,我的数据有多个非唯一的名称标签。我想创建第三列,这样非唯一名称的末尾就可以粘贴一个字母来创建唯一的名称 dat <- structure(list(id = c("172262", "172262", "172262", "172262", "172504", "172504", "172504", "172507", "172507", "172507"), name = c("Fam", "Fam", "Fam", "CM_fam", "CBT_Fam", "CB
dat <- structure(list(id = c("172262", "172262", "172262", "172262",
"172504", "172504", "172504", "172507", "172507", "172507"),
name = c("Fam", "Fam", "Fam", "CM_fam", "CBT_Fam", "CBT_Fam",
"CBT_Fam", "TAU", "CBT_Educ", "CBT_MI")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -10L))
您可以将
粘贴
或sprintf
与字母
一起使用
dat %>% group_by(id, name) %>% mutate(uname =
if (n() > 1) sprintf("%s_%s", name, letters[row_number()])
else name
)
# A tibble: 10 x 3
# Groups: id, name [6]
id name uname
<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\u by(id,name)%>%mutate(uname=
如果(n()>1)sprintf(“%s\u%s”,名称,字母[行号())
别称
)
#一个tibble:10x3
#组:id,名称[6]
id名称uname
1172262个家庭
2172262法姆法姆布
3172262家庭委员会
4172262公分/公分/公分/公分
5172504家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用
6 172504 CBT_Fam CBT_Fam_b
7 172504 CBT_Fam CBT_Fam_c
8172507头
9 172507 CBT_教育CBT_教育
10172507立方英尺/平方米立方英尺/平方米
对于tidyverse(dplyr所属)中的其他字符串操作,请参见stringr和glue。另一种可能性是:
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
或者使用seq_along()
代替n()
:
或者使用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
或:
您可以使用
ave
(基本R
)
转换(dat,唯一名称=
ave(名称,名称,乐趣=功能(x){
如果((l)只是为了带来一些数据。这里的表格风格:
library(data.table)
DT <- as.data.table(dat)
DT[, unique_name := if (.N > 1) paste(name, letters[1:.N], sep = "_")
else name,
by = .(id, name)]
库(data.table)
DT 1)粘贴(名称,字母[1:.N],sep=“389;”)
其他名称,
by=(id,name)]
但是,正如其他人指出的,您可能需要替换字母[1:.N]
只需1:.N
以防您有26个以上的重复名称。这里有很多选项可供选择,但如果您正在寻找一个相当简单的管道,并且可以使用不同格式的输出,您可以使用基本R:
library(dplyr)
dat %>%
group_by(id, name) %>%
mutate(unique_name = make.unique(name))
这将产生:
id name unique_name
<chr> <chr> <chr>
1 172262 Fam Fam
2 172262 Fam Fam.1
3 172262 Fam Fam.2
4 172262 CM_fam CM_fam
5 172504 CBT_Fam CBT_Fam
6 172504 CBT_Fam CBT_Fam.1
7 172504 CBT_Fam CBT_Fam.2
8 172507 TAU TAU
9 172507 CBT_Educ CBT_Educ
10 172507 CBT_MI CBT_MI
id名称唯一\u名称
1172262家
2 172262家庭1
3172262家庭2
4172262公分/公分/公分/公分
5172504家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用家庭用
6 172504 CBT_Fam CBT_Fam.1
7 172504 CBT_Fam CBT_Fam.2
8172507头
9 172507 CBT_教育CBT_教育
10172507立方英尺/平方米立方英尺/平方米
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)
transform(dat, unique_name =
ave(name,name, FUN = function(x) {
if((l <- length(x)) == 1) x
else paste0(x,"_",letters[seq(l)])
}))
# id name unique_name
# 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$unique_name <- chartr(
make.unique(dat$name,sep="_"),old="123456789",new="abcdefghi")
dat
# # A tibble: 10 x 3
# id name unique_name
# <chr> <chr> <chr>
# 1 172262 Fam Fam
# 2 172262 Fam Fam_a
# 3 172262 Fam Fam_b
# 4 172262 CM_fam CM_fam
# 5 172504 CBT_Fam CBT_Fam
# 6 172504 CBT_Fam CBT_Fam_a
# 7 172504 CBT_Fam CBT_Fam_b
# 8 172507 TAU TAU
# 9 172507 CBT_Educ CBT_Educ
# 10 172507 CBT_MI CBT_MI
library(data.table)
DT <- as.data.table(dat)
DT[, unique_name := if (.N > 1) paste(name, letters[1:.N], sep = "_")
else name,
by = .(id, name)]
library(dplyr)
dat %>%
group_by(id, name) %>%
mutate(unique_name = make.unique(name))
id name unique_name
<chr> <chr> <chr>
1 172262 Fam Fam
2 172262 Fam Fam.1
3 172262 Fam Fam.2
4 172262 CM_fam CM_fam
5 172504 CBT_Fam CBT_Fam
6 172504 CBT_Fam CBT_Fam.1
7 172504 CBT_Fam CBT_Fam.2
8 172507 TAU TAU
9 172507 CBT_Educ CBT_Educ
10 172507 CBT_MI CBT_MI