R语言按分隔符拆分键值对列并将键转为新列的问题
问题解决方法
错误原因
你遇到的报错是因为tidyr::separate的sep参数不支持stringr::fixed()生成的修饰符对象,直接传入普通字符串分隔符即可。
修正后的tidyverse代码
基于你的原有思路调整,可正常运行且处理无值键的NA为空字符串:
library(stringr) library(tidyr) library(dplyr) # 直接用字符串作为分隔符,无需fixed()修饰 KVsep <- ";" Vsep <- "=" newDF <- data %>% mutate(KVpairs = str_split(INFO, KVsep)) %>% unnest_longer(KVpairs) # 更规范的列表列拆分方式 separate(KVpairs, into = c("key", "value"), sep = Vsep, fill = "right") %>% # 无值键自动填充NA mutate(value = ifelse(is.na(value), "", value)) %>% # 将NA替换为空字符串 pivot_wider(names_from = key, values_from = value) %>% # 替代spread的高效新函数 select(-INFO)
大数据量优化方案
若数据量达数百万行,tidyverse方法效率有限,可改用data.table实现,速度提升明显:
library(data.table) library(stringr) setDT(data) # 拆分INFO为键值对列表 data[, KVpairs := str_split(INFO, ";")] # 展开列表为行,保留原始行号 data_long <- data[, .(KVpair = unlist(KVpairs)), by = .(rowid = seq_len(nrow(data)))] # 拆分键和值,无值键填充NA data_long[, c("key", "value") := tstrsplit(KVpair, "=", fill = "right")] # 将NA替换为空字符串 data_long[is.na(value), value := ""] # 转换为宽表 data_wide <- dcast(data_long, rowid ~ key, value.var = "value") # 移除行号列,得到最终结果 data_new <- data_wide[, !"rowid"]
结果验证
运行上述代码后,IMPUTED列会全部为空字符串,FREQ列正确提取对应值,其他所有存在的键都会生成对应列,完全符合需求。
内容的提问来源于stack exchange,提问作者curious
相关产品推荐
相关产品推荐

