R语言:为同名缺失clientid分配唯一不重复随机ID的问题
解决同名客户分配唯一随机ID的问题
你有包含clientname和clientid两列的数据,部分客户的clientid为NA,需求是:
- 同名客户分配相同的唯一随机ID
- 不同名客户的ID不重复
但使用以下代码后,同名客户的ID仍然不同:
df1 <- df %>% dplyr::group_by(clientname) %>% dplyr::mutate(clientid = ifelse(is.na(clientid), sample(1:10000), clientid))
示例输入数据
clientname <- c("Mr A", "Mr B", "Mr B", "Mr C", "Mr D") clientid <- c(NA,NA,NA,NA,1) df <- data.frame(clientname, clientid)
原代码输出问题
# A tibble: 5 x 2 # Groups: clientname [4] clientname clientid <chr> <dbl> 1 Mr A 948 2 Mr B 4004 3 Mr B 7888 # 同一客户ID不同 4 Mr C 4668 5 Mr D 1
问题原因
mutate中调用sample(1:10000)时,会对每一行单独生成随机数,即使分组后,每行仍会执行一次采样,导致同组内不同行ID不一致。同时原代码没有排除已存在的非NA ID,可能出现新生成ID与已有ID重复的情况。
解决方案
需要为每个需要分配ID的客户分组只生成一个随机ID,同时确保新ID不与已存在的ID重复。以下是两种实现方式:
方式1:先生成分组ID再合并
library(dplyr) # 示例数据 clientname <- c("Mr A", "Mr B", "Mr B", "Mr C", "Mr D") clientid <- c(NA,NA,NA,NA,1) df <- data.frame(clientname, clientid) # 获取已使用的ID,避免重复 used_ids <- df %>% filter(!is.na(clientid)) %>% pull(clientid) # 为需要分配ID的客户分组生成唯一随机ID new_id_map <- df %>% filter(is.na(clientid)) %>% distinct(clientname) %>% mutate(clientid = sample(setdiff(1:10000, used_ids), n(), replace = FALSE)) # 合并回原数据 df1 <- df %>% left_join(new_id_map, by = "clientname") %>% mutate(clientid = coalesce(clientid.x, clientid.y)) %>% # 优先取原ID,无则用新生成的ID select(clientname, clientid) # 查看结果 df1
方式2:分组内直接生成单个随机ID
df1 <- df %>% group_by(clientname) %>% mutate( clientid = ifelse( is.na(clientid), # 为每个分组仅生成1个随机ID,排除已使用的ID sample(setdiff(1:10000, df$clientid[!is.na(df$clientid)]), 1), clientid ) ) %>% ungroup()
期望输出
> df1 clientname clientid 1 Mr A 948 2 Mr B 4004 3 Mr B 4004 4 Mr C 4668 5 Mr D 1
内容的提问来源于stack exchange,提问作者user19779614
相关产品推荐
相关产品推荐

