[英]Assign unique ID to distinct values within Group with dplyr
問題:我需要為具有兩個分組級別的數據創建唯一的ID字段。 在此處的示例代碼中,它是Emp
和Color
。 該ID的結構應為:
Emp
+每個Color
唯一編號+重復Colors
序號。
這些值由句點分隔。
示例數據:
dat <- data.frame(Emp = c("A","A","A","B","B","C"),
Color = c("Red","Green","Green","Orange","Yellow","Brown"),
stringsAsFactors = FALSE)
該ID應該顯示為:
ID <- c("A.01.001", "A.02.001", "A.02.002", "B.01.001", "B.02.001", "C.01.001")
ID [1]“ A.01.001”“ A.02.001”“ A.02.002”“ B.01.001”“ B.02.001”“ C.01.001”
ID的三個字符后綴來記錄重復項,可以這樣完成:
group_by(dat, Emp, Color) %>%
mutate(suffix = str_pad(row_number(), width=3, side="left", pad="0"))
但是我無法為每個Emp
組分配連續編號給Color
的唯一出現。
我更喜歡dplyr解決方案,但是任何方法都將不勝感激。
使用data.table
和sprintf
:
library(data.table)
setDT(dat)[, ID := sprintf('%s.%02d.%03d',
Emp, rleid(Color), rowid(rleid(Color))),
by = Emp]
你得到:
> dat
Emp Color ID
1: A Red A.01.001
2: A Green A.02.001
3: A Green A.02.002
4: B Orange B.01.001
5: B Yellow B.02.001
6: C Brown C.01.001
工作原理:
setDT()
將dat
轉換為data.table
Emp
分組。 sprintf
函數創建ID
變量。 使用sprintf
您可以根據指定的格式輕松地將多個矢量粘貼在一起。 :=
的使用意味着data.table
通過引用進行更新。 %s
指示在第一部分(即Emp
)中使用字符串。 %02d
和%03d
表示數字需要在需要時由兩位或三位數字和前導零組成。 中間的點將按字面意義使用,因此包含在結果字符串中。 處理@jsta的注釋,如果Color
-column中的值不是連續的,則可以使用:
setDT(dat)[, r := as.integer(factor(Color, levels = unique(Color))), by = Emp
][, ID := sprintf('%s.%02d.%03d',
Emp, r, rowid(r)),
by = Emp][, r:= NULL]
這也將保持“ Color
列的顯示順序。 代替as.integer(factor(Color, levels = unique(Color)))
您還可以使用match(Color, unique(Color))
,如akrun所示。
在更大的數據集上實現上述內容以說明:
dat2 <- rbindlist(list(dat,dat))
dat2[, r := match(Color, unique(Color)), by = Emp
][, ID := sprintf('%s.%02d.%03d',
Emp, r, rowid(r)),
by = Emp]
讓您:
> dat2
Emp Color r ID
1: A Red 1 A.01.001
2: A Green 2 A.02.001
3: A Green 2 A.02.002
4: B Orange 1 B.01.001
5: B Yellow 2 B.02.001
6: C Brown 1 C.01.001
7: A Red 1 A.01.002
8: A Green 2 A.02.003
9: A Green 2 A.02.004
10: B Orange 1 B.01.002
11: B Yellow 2 B.02.002
12: C Brown 1 C.01.002
我們可以試試
dat %>%
group_by(Emp) %>%
mutate(temp = match(Color, unique(Color)),
temp2 = duplicated(Color)+1,
ID = sprintf("%s.%02d.%03d", Emp, temp, temp2))%>%
select(-temp, -temp2)
# Emp Color ID
# <chr> <chr> <chr>
#1 A Red A.01.001
#2 A Green A.02.001
#3 A Green A.02.002
#4 B Orange B.01.001
#5 B Yellow B.02.001
#6 C Brown C.01.001
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.