r - 使用 dplyr 为 Group 中的不同值分配唯一 ID

标签 r dplyr

问题:我需要为具有两个分组级别的数据创建一个唯一的 ID 字段。在这里的示例代码中,它是 EmpColor。 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.tablesprintf:

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-列中的值不连续可以使用:

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

关于r - 使用 dplyr 为 Group 中的不同值分配唯一 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42537689/

相关文章:

r - lavaan 纵向不变性 CFA 与 R 中的 2 因子模型

c - Metropolis Hastings 线性回归模型

r - spark_write_csv dplyr 函数的 options 参数是什么?

使用 group_by 时重新排序 NA 的位置

r - 是否可以将 Alglib 与 Rcpp 一起使用?

r - GenMatch() 中的 pop.size 参数分别为 genoud()

r - grepl 用于 dplyr sql 表?

r - 在 dplyr 管道运算符中组合条件评估 (%>%)

r - dplyr : row_number() from tbl_dt inconsistent to tbl_df 中的唯一行

javascript - 如何指定行/列来应用R Shiny的回调函数?