如何在R语言中将单列元素拆分并生成多列存在标记列?
解决方案
可以使用tidyverse工具包高效处理这个需求,步骤清晰且代码简洁:
方法一:使用tidyverse工具链
library(tidyverse) # 原始数据集 df <- data.frame(identifier = c("a","b","b","c"), disease = c("heart, lung","lung, heart,,","lung, heart, heart, liver", "kidney, brain ")) # 数据处理流程 processed_df <- df %>% # 清洗疾病列:替换多逗号为单逗号、去除首尾空格、拆分疾病为列表 mutate(disease = str_replace_all(disease, ",+", ","), disease = str_trim(disease), disease = str_split(disease, ", ")) %>% # 将列表形式的疾病展开为多行 unnest(disease) %>% # 标记存在的疾病为Yes mutate(status = "Yes") %>% # 转换为宽格式,缺失值填充为No pivot_wider(names_from = disease, values_from = status, values_fill = "No") # 输出结果 print(processed_df)
执行后得到的结果:
# A tibble: 4 × 6 identifier heart lung liver kidney brain <chr> <chr> <chr> <chr> <chr> <chr> 1 a Yes Yes No No No 2 b Yes Yes No No No 3 b Yes Yes Yes No No 4 c No No No Yes Yes
关键步骤说明
str_replace_all(disease, ",+", ","):把连续多个逗号替换为单个,解决类似lung, heart,,的格式问题str_trim(disease):去除字符串首尾空格,避免拆分出空值或带空格的疾病名称str_split(disease, ", "):将每个疾病字符串按,拆分为列表,方便后续展开unnest(disease):把列表形式的疾病列展开为多行,让每个疾病对应一行数据pivot_wider:将长格式数据转换为宽格式,自动按identifier分组,缺失的疾病标记填充为No
方法二:使用基础R实现
如果不想依赖第三方包,也可以用基础R代码完成:
# 原始数据 df <- data.frame(identifier = c("a","b","b","c"), disease = c("heart, lung","lung, heart,,","lung, heart, heart, liver", "kidney, brain ")) # 清洗疾病列 df$disease <- gsub(",+", ",", df$disease) df$disease <- trimws(df$disease) # 拆分疾病并提取所有唯一疾病名称 disease_list <- strsplit(df$disease, ", ") all_diseases <- unique(unlist(disease_list)) # 循环生成每个疾病的标记列 for(d in all_diseases){ df[[d]] <- sapply(disease_list, function(x) ifelse(d %in% x, "Yes", "No")) } # 移除原disease列 df <- df[, !(names(df) %in% "disease")] # 输出结果 print(df)
这个方法通过循环遍历所有唯一疾病,逐行检查是否包含该疾病,从而生成对应的Yes/No标记列。
内容的提问来源于stack exchange,提问作者Ahmed
相关产品推荐
相关产品推荐

