如何在R中更优雅地将含大括号的字符串向量转为命名向量?
更简洁的R字符串向量处理解法
需求回顾
给定字符串向量:
originalvector <- c("apple pie {we have some text here}", "banana{something{something}}", "cherry {asd9asdjsaf}", "banana {monkey}")
需完成:
- 以第一个
{为分隔符,拆分出名称({之前的内容)和元素值(保留{及之后的内容) - 重复名称对应的元素值用
\n合并 - 最终输出命名字符串向量
你的现有实现
library(dplyr) elemNames <- originalvector %>% gsub("\\{.*", "", .) # 提取名称 elems <- originalvector %>% sub(".*?\\{", "{", .) # 提取元素值 names(elems) <- elemNames newvector <- sapply(unique(elemNames), \(elemName) { elems[grep(elemName, names(elems))] %>% {paste(.,collapse = "\n")} }) %>% setNames(unique(elemNames))
更优雅的解法
1. 可读性优先:dplyr + tibble 管道流
无需手动处理命名和迭代,用分组聚合一步到位:
library(dplyr) library(tibble) originalvector %>% enframe(name = NULL) %>% mutate( name = sub("\\{.*", "", value), content = sub(".*?\\{", "{", value) ) %>% group_by(name) %>% summarise(content = paste(content, collapse = "\n")) %>% deframe()
enframe把向量转成数据框,简化后续字段处理- 正则拆分精准分离名称和带
{的内容 group_by+summarise自动完成重复名称的内容合并deframe直接将处理后的数据框转回命名字符向量
2. 无依赖:基础R一行实现
不需要加载任何扩展包,用原生函数组合完成:
with( setNames( do.call(rbind, strsplit(originalvector, "(?<=^[^\\{]*)\\{", perl = TRUE)), c("name", "rest") ), tapply(paste0("{", rest), name, paste, collapse = "\n") )
strsplit借助Perl正则的正向预查,精准在第一个{位置拆分字符串setNames为拆分后的矩阵字段命名,方便with快速调用tapply按名称分组,自动合并同名称的内容并补回{前缀
验证输出
两种解法都会得到你期望的结果:
apple pie banana "apple pie {we have some text here}" "{something{something}}\n{monkey}" cherry "cherry {asd9asdjsaf}"
内容的提问来源于stack exchange,提问作者Aku-Ville Lehtimäki
相关产品推荐
相关产品推荐

