R语言嵌套循环拆分数据报错:j==scenario需长度1而非6的解决咨询
问题原因
报错的根儿在俩地方:
- 你定义的循环变量叫
scenario,刚好和数据框里的列名重了,导致filter(j == scenario)里的scenario指的是你外面那个有6个元素的列表,不是数据框的列,一比较就出现长度不匹配的问题。 top_20一开始是空列表,直接往top_20[[i]][[j]]塞数据,程序找不到对应的位置,也容易出问题。
修正后的嵌套循环代码
先改变量名避免冲突,再提前初始化内层列表,最后把filter条件写对:
pzs <- list(1, 2, 3, 4, 5) # 把场景列表改名叫scenarios,和列名区分开 scenarios <- list("Scenario_1", "Scenario_2", "Scenario_3", "Scenario_4", "Scenario_5", "Scenario_6") top_20 <- list() for(i in pzs){ # 先给当前pz创建一个空的子列表 top_20[[i]] <- list() for(j in scenarios){ top_20[[i]][[j]] <- data %>% # 数据框的pz列等于循环变量i filter(pz == i) %>% # 数据框的scenario列等于循环变量j filter(scenario == j) %>% arrange(desc(sales)) %>% head(n=10) } }
更省心的替代写法(无需嵌套循环)
用dplyr和tidyr的函数能一步搞定,代码更简洁易维护:
library(dplyr) library(tidyr) top_20_list <- data %>% # 按pz和scenario分组 group_by(pz, scenario) %>% # 每组按sales降序排序,取前10条 arrange(desc(sales), .by_group = TRUE) %>% slice_head(n=10) %>% # 把每组数据嵌套成列表格式 nest(data = -c(pz, scenario)) %>% # 把scenario转成列,让结构和循环结果一致 pivot_wider(names_from = scenario, values_from = data) %>% # 按pz拆分成外层列表 split(.$pz) %>% # 去掉每个子列表里的pz列,转成纯数据列表 lapply(function(x) x %>% select(-pz) %>% as.list())
内容的提问来源于stack exchange,提问作者L-dan
相关产品推荐
相关产品推荐

