按家庭组为多列创建哑变量,处理特殊值与缺失值
问题描述
现有家庭花名册数据框:
hhroster <- data.frame(HHID = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6), INDID = c(1, 2, 3, 1, 2, 1, 2, 3, 4, 1, 2, 3, 1, 2, 1), response_1 = c("yes", "no", "yes", "yes", "no", "no", "no", "no", "no", "yes", "yes", "no", "yes", "yes", "no"), response_2 = c("no", "no", "yes", "no", "no", "no", "yes", "no", "no", "no", "no", "no", "yes", "yes", "no"))
需求
- 基于
HHID(家庭ID)聚合,为每个响应列创建家庭层面哑变量:- 若家庭中至少1位成员回答"yes",哑变量取值为
1; - 若家庭所有成员的响应均为
DK、RF或缺失值(NA),则哑变量取值为NA(而非0);
- 若家庭中至少1位成员回答"yes",哑变量取值为
- 期望输出:
hh <- data.frame(HHID = c(1, 2, 3, 4, 5, 6), HH_response_1 = c(1, 1, 0, 1, 1, 0), HH_response_2 = c(1, 0, 1, 0, 1, 0))
解决方案
以下提供两种常用的R实现方式,均满足特殊值处理逻辑:
方法1:Base R 原生实现
适合不依赖第三方包的场景:
# 定义无效响应集合(DK/RF/缺失值) invalid_responses <- c("DK", "RF", NA) # 按HHID分组聚合响应列 hh_agg <- aggregate( . ~ HHID, data = hhroster[, c("HHID", "response_1", "response_2")], FUN = function(x) { # 过滤当前家庭的无效响应 valid_vals <- x[!x %in% invalid_responses] # 全无效则返回NA,否则判断是否存在yes并转为整数 if (length(valid_vals) == 0) { NA_real_ } else { as.integer(any(valid_vals == "yes")) } } ) # 重命名列以匹配期望输出格式 colnames(hh_agg) <- c("HHID", "HH_response_1", "HH_response_2")
方法2:Tidyverse(dplyr)实现
管道式语法更简洁,适合批量处理多列:
library(dplyr) invalid_responses <- c("DK", "RF", NA) hh_agg <- hhroster %>% # 按家庭分组 group_by(HHID) %>% # 批量处理所有响应列 summarise( across( starts_with("response_"), ~ { valid_vals <- .x[!.x %in% invalid_responses] if (length(valid_vals) == 0) NA_real_ else as.integer(any(valid_vals == "yes")) } ), .groups = "drop" # 取消分组状态 ) %>% # 重命名列前缀 rename_with(~ gsub("response_", "HH_response_", .x), starts_with("response_"))
验证
执行任意一种方法后,hh_agg将与期望输出一致;若某家庭所有成员的响应均为无效值,对应哑变量会自动设为NA。
内容的提问来源于stack exchange,提问作者Stephen Okiya
相关产品推荐
相关产品推荐

