R语言中如何将上层列表名称拆分后的元素按指定顺序追加到子列表元素名称中
我来帮你搞定这个列表名称修改的问题!先理清楚你的需求:你有一个嵌套列表,上层的两个列表叫A_B和S_D,每个里面又有4个元素——前两个叫something,后两个叫gotta give,现在要把上层名称拆成下划线前后的部分,按指定顺序追加到对应子元素的名称后面,比如A_B下面的要变成something_A、something_B、gotta give_A、gotta give_B,S_D下面的对应变成something_S、something_D、gotta give_S、gotta give_D对吧?
首先先把你的初始代码放出来,方便大家复现你的场景:
# 构建初始列表 list1 = list(mtcars, airquality, mtcars, airquality) combined_list = list(list1, list1) names(combined_list) = c('A_B','S_D') combined_list = lapply(combined_list, function(x) setNames(x, c(rep('something', 2), rep('gotta give',2))))
你之前尝试的代码顺序有点搞反了,导致生成的名称不符合预期。这里给你两种可行的解决方法:
方法一:基础R原生实现
我们可以直接遍历上层列表的每个元素,同时拿到它的名称,拆分后按需求拼接新名称:
# 遍历上层列表的名称,逐个处理每个子列表 combined_list_final = lapply(names(combined_list), function(name) { # 把当前上层名称拆分成下划线前后的两部分(比如A_B拆成c("A", "B")) name_parts = strsplit(name, "_")[[1]] # 获取当前要处理的子列表 current_sub_list = combined_list[[name]] # 按需求生成新名称:前两个是something+拆分的两个部分,后两个是gotta give+拆分的两个部分 new_names = c( paste0("something_", name_parts), paste0("gotta give_", name_parts) ) # 给子列表设置新名称 setNames(current_sub_list, new_names) }) # 别忘了给最终的上层列表保留原来的名称 names(combined_list_final) = names(combined_list)
运行这段代码后,你检查combined_list_final[[1]]的元素名称,就是你想要的something_A、something_B、gotta give_A、gotta give_B,combined_list_final[[2]]的名称也完全符合预期。
方法二:用purrr包简化代码(更直观)
如果你平时习惯用tidyverse系列工具,purrr包的imap函数可以同时拿到子列表的内容和对应的上层名称,代码会更简洁:
library(purrr) combined_list_final = imap(combined_list, function(sub_list, upper_name) { # 拆分上层名称 name_parts = strsplit(upper_name, "_")[[1]] # 生成新名称 new_names = c(paste0("something_", name_parts), paste0("gotta give_", name_parts)) # 设置新名称 setNames(sub_list, new_names) })
这里sub_list就是当前要处理的子列表内容,upper_name就是对应的上层列表名称,省去了手动处理名称索引的步骤,逻辑更清晰。
简单说下你之前代码的问题:你是先遍历拆分后的名称部分,再遍历上层列表,这样生成的名称顺序是先所有something加A,再所有something加B,和你要的“每个子列表里先something_A、something_B,再gotta give_A、gotta give_B”的顺序不符,而我们的方法是先处理单个上层列表,拆分后直接按需求拼接前两个和后两个名称,顺序就完全对了。
备注:内容来源于stack exchange,提问作者12666727b9

