基于用户名生成唯一ID:dplyr与Stata实现对比
在dplyr中为用户名生成唯一ID(替代Stata的
egen group功能) 问题背景
我有一份Reddit数据集,每行代表一条Reddit帖子并包含用户名信息,不同用户名的发帖量差异较大。我希望为每个用户名生成唯一ID,但使用以下dplyr代码后,生成的是用户帖子的序号而非用户名的唯一ID:
df <- df %>% group_by(username) %>% mutate(id = row_number())%>% relocate(id)
数据示例
原数据前5行(仅展示date和username字段):
dput(df[1:5,c(2,3)])
输出:
structure(list(date = structure(c(15149, 15150, 15150, 15150, 15150), class = "Date"), username = c("تتطور", "عاطله فقط", "قصه ألم", "بشروني بوظيفة", "الواعده")), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L), groups = structure(list(username = c("الواعده", "بشروني بوظيفة", "تتطور", "عاطله فقط", "قصه ألم"), .rows = structure(list(5L, 4L, 1L, 2L, 3L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L), .drop = TRUE))
运行错误代码后,前10行的id和username字段输出:
dput(df[1:10,c(1,4)])
输出:
structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 3L), username = c("تتطور", "عاطله فقط", "قصه ألم", "بشروني بوظيفة", "الواعده", "ماخليتوآ لي اسم", "مرافئ ساكنه", "معتوقة", "تتطور", "تتطور")), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -10L), groups = structure(list(username = c("الواعده", "بشروني بوظيفة", "تتطور", "عاطله فقط", "قصه ألم", "ماخليتوآ لي اسم", "مرافئ ساكنه", "معتوقة"), .rows = structure(list(5L, 4L, c(1L, 9L, 10L), 2L, 3L, 6L, 7L, 8L), ptype = integer(0), class = c("vctrs_list_of", "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -8L), .drop = TRUE))
在Stata中,我可以通过以下代码实现为每个用户名生成唯一ID:
// create an id variable per username egen id = group(username)
解决方案
在dplyr中,有几种方法可以实现类似Stata egen group的功能,为每个用户名分配全局唯一ID:
方法1:使用cur_group_id()(推荐)
cur_group_id()会为每个分组分配唯一的整数ID,结合group_by()使用即可:
df <- df %>% group_by(username) %>% mutate(id = cur_group_id()) %>% ungroup() %>% // 取消分组,避免后续操作受分组影响 relocate(id)
- 特点:ID按分组的排序顺序分配(默认按用户名的字符顺序排序)
- 注意:必须先通过
group_by(username)分组,再调用cur_group_id()
方法2:使用factor转换为整数
将用户名转为因子类型,再转换为整数,每个因子水平对应唯一ID:
// 按用户名的字符顺序分配ID df <- df %>% mutate(id = as.integer(factor(username))) %>% relocate(id) // 按用户名首次出现的顺序分配ID(更贴近Stata默认的`egen group`行为) df <- df %>% mutate(id = as.integer(factor(username, levels = unique(username)))) %>% relocate(id)
- 特点:灵活控制ID的分配顺序,通过
levels参数指定ID的排序规则
方法3:使用group_indices()(旧版函数)
group_indices()是cur_group_id()的前身,功能类似,但已不再推荐使用:
df <- df %>% mutate(id = group_indices(., username)) %>% relocate(id)
内容的提问来源于stack exchange,提问作者nesta1990
相关产品推荐
相关产品推荐

