如何为MainID/DOB相同且SubID不同的数据行随机分配0或1?
问题描述
原始数据集
MainID SubID DOB BMI 1234 1234_A Feb-19-2024 10.1 1235 1235_A Jan-11-2023 17.23 1235 1235_B Jan-11-2023 19.11 5136 5136_A May-17-2021 21.87 5136 5136_B May-17-2021 14.18 5136 5136_C May-17-2021 18.11 3357 3357-A Oct-06-2023 24.10 9124 9124-B July-01-2021 12.09 9124 9124-B July-01-2021 15.06
需求说明
仅当行的MainID和DOB相同但SubID不同时,为这些行随机分配0或1;其余情况(单一行、MainID和DOB相同但SubID也相同的重复行)统一分配0,期望输出如下:
MainID SubID DOB BMI Col1 1234 1234_A Feb-19-2024 10.1 0 1235 1235_A Jan-11-2023 17.23 0 1235 1235_B Jan-11-2023 19.11 1 3357 3357-A Oct-06-2023 24.10 0 5136 5136_A May-17-2021 21.87 0 5136 5136_B May-17-2021 14.18 0 5136 5136_C May-17-2021 18.11 1 9124 9124-B July-01-2021 12.09 0 9124 9124-B July-01-2021 15.06 0
用户尝试使用ifelse和duplicated(df[c("MainID", "DOB")])的方法未成功,需要可行的解决思路。
解决方案
方法一:使用dplyr分组处理
核心思路是按MainID和DOB分组,先判断组内是否存在不同SubID且无重复SubID,再针对性分配值:
library(dplyr) # 读取数据集 df <- read.table(text = " MainID SubID DOB BMI 1234 1234_A Feb-19-2024 10.1 1235 1235_A Jan-11-2023 17.23 1235 1235_B Jan-11-2023 19.11 5136 5136_A May-17-2021 21.87 5136 5136_B May-17-2021 14.18 5136 5136_C May-17-2021 18.11 3357 3357-A Oct-06-2023 24.10 9124 9124-B July-01-2021 12.09 9124 9124-B July-01-2021 15.06 ", header = TRUE, stringsAsFactors = FALSE) # 生成目标列Col1 df <- df %>% group_by(MainID, DOB) %>% mutate( # 标记组内是否有多个不同SubID has_multiple_subid = n_distinct(SubID) > 1, # 标记组内是否有重复SubID has_dup_subid = any(duplicated(SubID)), # 按规则分配0/1 Col1 = ifelse(has_multiple_subid & !has_dup_subid, sample(c(0,1), n(), replace = TRUE), 0) ) %>% select(-has_multiple_subid, -has_dup_subid) %>% ungroup() print(df)
方法二:Base R实现
无需依赖第三方包,用base R的分组函数完成处理:
# 读取数据集 df <- read.table(text = " MainID SubID DOB BMI 1234 1234_A Feb-19-2024 10.1 1235 1235_A Jan-11-2023 17.23 1235 1235_B Jan-11-2023 19.11 5136 5136_A May-17-2021 21.87 5136 5136_B May-17-2021 14.18 5136 5136_C May-17-2021 18.11 3357 3357-A Oct-06-2023 24.10 9124 9124-B July-01-2021 12.09 9124 9124-B July-01-2021 15.06 ", header = TRUE, stringsAsFactors = FALSE) # 按MainID+DOB分组处理 df$Col1 <- unlist(by(df, list(df$MainID, df$DOB), function(group) { has_multiple_subid <- length(unique(group$SubID)) > 1 has_dup_subid <- any(duplicated(group$SubID)) if (has_multiple_subid && !has_dup_subid) { sample(c(0,1), nrow(group), replace = TRUE) } else { rep(0, nrow(group)) } })) print(df)
关键逻辑说明
- 以
MainID和DOB为分组单元,这是判断的基础; - 两个核心判断条件:
has_multiple_subid:组内存在多个不同的SubID(排除单一行的情况);has_dup_subid:组内有重复的SubID(排除同一SubID重复行的情况);
- 仅当两个条件同时满足时,才随机分配0/1,其余情况统一设为0。
内容的提问来源于stack exchange,提问作者Sundown Brownbear
相关产品推荐
相关产品推荐

