R语言中替换unlist()新增的点为/且保留其余原有圆点的实现方法
解决方法
核心逻辑:unlist()默认会用.作为分隔符拼接不同层级的元素名,要区分原有.和新增的拼接符,有两种成熟实现方案:
方案1:针对你当前场景的高效解法
你现有代码是遍历外层list的名称,匹配内层为TRUE的元素名,完全可以手动用/拼接两级名称,不需要依赖unlist()的自动命名,完全不会修改原有字符串自带的.:
# 注意:in是R的关键字,不能作为变量名,这里重命名为lst lst <- list(a.study = c(scale.1 = TRUE, outcome = FALSE), scale.1 = c(a.study = FALSE, outcome = FALSE)) out <- unlist(Filter(length, lapply(names(lst), function(i) { # 直接拼接外层名称+符合条件的内层名称,分隔符指定为/ paste(i, names(which(unlist(lst[i]) == TRUE)), sep = "/") }))) print(out) # 输出:"a.study/scale.1"
方案2:任意多层级list通用解法
如果你的list是不确定层级的结构,可以用「临时字符替换」的通用方案,逻辑是先把原有.替换为一个不可能出现在名称里的罕见字符,等unlist()完成拼接后再替换回来:
lst <- list(a.study = c(scale.1 = TRUE, outcome = FALSE), scale.1 = c(a.study = FALSE, outcome = FALSE)) # 递归替换所有层级名称中的.为罕见临时字符(这里用\001回车符,正常业务场景不会出现在命名中) replace_name_dot <- function(x) { if (is.list(x)) { names(x) <- gsub("\\.", "\001", names(x)) lapply(x, replace_name_dot) } else x } processed_lst <- replace_name_dot(lst) # 筛选符合条件的元素后,先把临时字符换回.,再把unlist新增的.替换为/ out <- names(unlist(processed_lst))[unlist(processed_lst) == TRUE] out <- gsub("\\.", "/", gsub("\001", ".", out)) print(out) # 输出:"a.study/scale.1"
内容的提问来源于stack exchange,提问作者Simon Harmel
相关产品推荐
相关产品推荐

