You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于用户名生成唯一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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 02:20:39