如何用for循环对比DataFrame与向量值,生成疾病有无标识列?
解决患者疾病编码的0/1标记列生成问题
我有一个记录患者所患疾病的DataFrame,每种疾病以数字形式存储(多列对应患者的不同疾病记录);另外有一列存储需要检查的疾病值。想要遍历这些待检查值,为每个值生成一列,用1表示患者患该疾病、0表示未患病,但现有代码没达到预期。
原尝试代码:
for(i in sample$disease){ for(j in patient_illness){ name<- paste("icd", i, sep="") assign( name, ifelse( any(j==i, na.rm=T), 1, 0 ) ) }}
原代码问题分析
any(j==i)会判断整列是否存在目标疾病编码,返回单个布尔值,最终每个icdxx变量只是一个单值(1或0),不是对应每个患者的标记向量- 嵌套循环+
assign的逻辑会重复覆盖变量,无法保留每个患者的独立标记结果
正确实现方式
循环实现(直观版)
# 遍历每个待检查的疾病编码 for(disease_code in sample$disease){ # 生成目标列名 col_name <- paste0("icd_", disease_code) # 按行检查患者是否患有该疾病,生成0/1标记 patient_illness[[col_name]] <- apply(patient_illness, 1, function(row){ ifelse(any(row == disease_code, na.rm = TRUE), 1, 0) }) }
向量化实现(高效版,推荐)
在R中优先用向量化操作替代循环,性能更优:
# 提取去重后的待检查疾病编码 target_codes <- unique(sample$disease) # 批量生成所有标记列 result_cols <- lapply(target_codes, function(code){ # 统计每行中匹配目标编码的数量,大于0则标记为1 as.integer(rowSums(patient_illness == code, na.rm = TRUE) > 0) }) # 转换为DataFrame并命名列 result_df <- do.call(cbind, result_cols) colnames(result_df) <- paste0("icd_", target_codes) # 合并到原患者疾病DataFrame中 patient_illness <- cbind(patient_illness, result_df)
代码说明
apply(patient_illness, 1, ...):按行遍历患者的所有疾病列,判断是否包含目标编码rowSums(..., na.rm=TRUE) > 0:通过求和快速判断每行是否存在目标编码,避免逐行循环的性能损耗- 两种方法都会直接将生成的0/1标记列添加到原DataFrame中,无需用
assign创建独立变量
内容的提问来源于stack exchange,提问作者hoon99
相关产品推荐
相关产品推荐

