R语言中按家庭随机选取成员的实现方案(单成员家庭必选)
R语言中按家庭随机选取成员的实现方案(单成员家庭必选)
嘿,这个需求用dplyr完全可以轻松实现,我来给你一步步讲清楚:
首先,先修正一下你创建数据框的方式——用cbind再转成数据框会导致所有列被统一成字符/因子类型,直接用data.frame()创建更稳妥:
FAMID <- c(1,1,2,3,3,4,4,5,6) IID <- c(1,2,2,1,2,1,2,1,2) Value <- c(3,6,3,5,6,7,0,4,6) # 直接创建数据框,保留原始数值类型 df <- data.frame(FAMID, IID, Value)
接下来就是核心逻辑:按FAMID分组后,每组随机抽取1条记录。对于只有单个成员的家庭,sample_n会自动保留唯一的那条,完全符合你的要求:
library(dplyr) # 设置随机种子(可选,让结果可重复) set.seed(123) # 按家庭分组 -> 每组随机选1个成员 -> 取消分组 selected_df <- df %>% group_by(FAMID) %>% sample_n(size = 1, replace = FALSE) %>% ungroup() # 查看结果 selected_df
运行后你会得到类似这样的输出(因为随机抽样,每次结果可能略有不同,但单成员家庭一定会被保留):
# A tibble: 6 × 3 FAMID IID Value <dbl> <dbl> <dbl> 1 1 1 3 2 2 2 3 3 3 2 6 4 4 1 7 5 5 1 4 6 6 2 6
简单解释下代码逻辑:
group_by(FAMID):把数据按家庭ID分组,确保后续操作都是针对每个家庭独立进行的sample_n(size = 1):从每个分组里随机选取1条记录,当分组只有1条记录时,直接返回该记录ungroup():取消分组,让结果回到普通数据框格式
如果你不想用dplyr,也可以用基础R的split() + lapply()组合实现,不过dplyr的写法更直观易读:
set.seed(123) # 按家庭拆分数据,每组随机选1行,再合并回数据框 selected_df_base <- do.call(rbind, lapply(split(df, df$FAMID), function(x) x[sample(nrow(x), 1), ]))
备注:内容来源于stack exchange,提问作者JuanJMV
相关产品推荐
相关产品推荐

