R语言:for循环提取数据框列生成列表时遇索引错误求解
问题描述
我有一个包含数千列的dataframefull_data,列名格式为城市名_年份(例如London_2022、London_2032、HonKong_2022、HonKong_2032),存储不同年份的城市人口数据。另外有一个由城市向量组成的列表:
list_cities <- list(List_Cities_1, List_Cities_2)
我想生成一个新列表,其中每个元素是从full_data中提取对应城市所有年份列的dataframe。尝试了以下代码后报错:
df_list <- list() for (list in list_cities) { # 选择目标列 selected_cols <- select(full_data, starts_with(paste0(list, "_"))) # 将dataframe添加到列表中 df_list[[list]] <- selected_cols }
错误信息:
Error in [[<-(tmp, signature, value = selected_cols) : no such index at level 1
错误原因
- 索引错误:试图用整个城市向量
list作为列表df_list的索引(df_list[[list]]),但列表的索引只能是整数或字符串,不能直接用向量。 - 列选择逻辑问题:
starts_with(paste0(list, "_"))当list是多元素向量时,无法生成有效的匹配条件——starts_with仅接受单个字符串,不能同时匹配多个城市前缀。
修正方案
方案一:修正for循环
用循环的位置索引赋值,同时改用正则表达式匹配多城市的列:
df_list <- list() # 遍历list_cities的每个元素,用位置i作为索引 for (i in seq_along(list_cities)) { current_cities <- list_cities[[i]] # 生成匹配所有目标城市的正则表达式:以任意目标城市开头,后跟_ pattern <- paste0("^(", paste(current_cities, collapse = "|"), ")_") # 匹配符合条件的列 selected_cols <- full_data %>% select(matches(pattern)) # 用位置索引添加到df_list df_list[[i]] <- selected_cols # 可选:给列表元素命名,方便后续调用 names(df_list)[i] <- paste0("Cities_Group_", i) }
方案二:用lapply简洁实现(推荐)
R中处理列表类操作,lapply比for循环更简洁高效:
df_list <- lapply(list_cities, function(cities) { pattern <- paste0("^(", paste(cities, collapse = "|"), ")_") full_data %>% select(matches(pattern)) }) # 可选:给列表元素命名 names(df_list) <- paste0("Cities_Group_", seq_along(df_list))
补充说明
- 如果
list_cities的子向量已有命名,可直接用这些名字给df_list命名:names(df_list) <- names(list_cities) - 若使用基础R而非tidyverse,可将
select(matches(pattern))替换为:full_data[, grepl(pattern, colnames(full_data))]
内容的提问来源于stack exchange,提问作者iturrizaga
相关产品推荐
相关产品推荐

