如何用dplyr按组为ID生成基于日期排序的有序数字编码
问题
现有数据集:
group id date G1 A 12/10/2007 G1 A 13/10/2007 G1 A 14/10/2007 G1 B 15/10/2007 G1 B 16/10/2007 G1 A 17/10/2007 G2 A 25/10/2007 G2 A 26/10/2007 G2 C 27/10/2007 G2 B 28/10/2007 G2 B 29/10/2007 G2 A 30/10/2007
需要新增id_new列,按group分组,将id转换为从1开始的有序数字,编码顺序由id在组内的首次出现日期决定(示例中日期已排序)。同一id在不同组可对应不同编码,期望输出如下:
group id date id_new G1 A 12/10/2007 1 G1 A 13/10/2007 1 G1 A 14/10/2007 1 G1 B 15/10/2007 2 G1 B 16/10/2007 2 G1 A 17/10/2007 1 G2 A 25/10/2007 1 G2 A 26/10/2007 1 G2 C 27/10/2007 2 G2 B 28/10/2007 3 G2 B 29/10/2007 3 G2 A 30/10/2007 1
已知可通过dplyr实现,已确定使用group_by(group),但不确定后续操作。
可复现数据集:
df <- structure(c("G1", "G1", "G1", "G1", "G1", "G1", "G2", "G2", "G2", "G2", "G2", "G2", "A", "A", "A", "B", "B", "A", "A", "A", "C", "B", "B", "A", "12/10/2007", "13/10/2007", "14/10/2007", "15/10/2007", "16/10/2007", "17/10/2007", "25/10/2007", "26/10/2007", "27/10/2007", "28/10/2007", "29/10/2007", "30/10/2007"), dim = c(12L, 3L), dimnames = list( NULL, c("group", "id", "date"))) |> as.data.frame()
解决方案
使用dplyr的分组操作,结合match()或factor()实现编码:
方法1:使用match()
核心逻辑是按组获取id的首次出现顺序,再通过match()映射每个id到对应的编码:
library(dplyr) df_result <- df |> group_by(group) |> mutate( id_new = match(id, unique(id[order(date)])) ) |> ungroup()
方法2:使用factor()
将id转为因子,指定水平为按日期排序的唯一id,再转为整数:
df_result <- df |> group_by(group) |> mutate( id_new = as.integer(factor(id, levels = unique(id[order(date)]))) ) |> ungroup()
结果验证
运行代码后得到的结果与期望一致:
# A tibble: 12 × 4 group id date id_new <chr> <chr> <chr> <int> 1 G1 A 12/10/2007 1 2 G1 A 13/10/2007 1 3 G1 A 14/10/2007 1 4 G1 B 15/10/2007 2 5 G1 B 16/10/2007 2 6 G1 A 17/10/2007 1 7 G2 A 25/10/2007 1 8 G2 A 26/10/2007 1 9 G2 C 27/10/2007 2 10 G2 B 28/10/2007 3 11 G2 B 29/10/2007 3 12 G2 A 30/10/2007 1
内容的提问来源于stack exchange,提问作者mto23
相关产品推荐
相关产品推荐

