R语言提取列表内数据框名称子串填充对应year列的实现方法
问题根因
原有代码运行不符合预期,核心是两个问题:
- 构造
df_list时没有给列表元素绑定对应的数据框原始名称,此时调用names(df_list)会返回空值,无法提取年份子串 - 普通
lapply仅遍历列表内的元素本身,不会同步传递元素对应的名称/位置索引,你在循环内调用names(df_list)拿到的是整个列表的名称向量,不是当前处理元素对应的单独名称,赋值逻辑完全错误。
实现代码
第一步:给列表元素绑定名称
你可以在构造列表时直接命名,从根源避免问题,这是最推荐的写法:
# 构造列表时直接指定元素名 df_list <- list( crops_1990.tempor = data.frame(study_unit=c("unit1", "unit2", "unit3"), cropp=c("crop1", "crop2", "crop3"), area=c(1,2,3), year=NA), crops_1991.tempor = data.frame(study_unit=c("unit1", "unit2", "unit3"), cropp=c("crop1", "crop2", "crop3"), area=c(4,5,6), year=NA), crops_1992.tempor = data.frame(study_unit=c("unit1", "unit2", "unit3"), cropp=c("crop1", "crop2", "crop3"), area=c(7,8,9), year=NA) )
如果已经按原有方式创建完无名称的列表,直接补命名即可:
names(df_list) <- c("crops_1990.tempor", "crops_1991.tempor", "crops_1992.tempor")
第二步:批量填充year列
基础R方案(无需安装额外包)
用mapply同时遍历列表元素和对应名称,逐个赋值即可,注意必须加SIMPLIFY = FALSE保证输出是列表格式:
df_list_fixed <- mapply(FUN = function(current_df, df_name) { # 从名称第7-10位截取年份 fill_year <- substring(df_name, 7, 10) # 给当前数据框所有行的year列填充对应年份,R自动做向量长度对齐 current_df$year <- fill_year return(current_df) }, df_list, names(df_list), SIMPLIFY = FALSE)
tidyverse方案(写法更简洁)
如果已安装purrr包,可以用imap函数,它会自动把列表元素的名称作为第二个参数传入自定义函数,代码更精简:
library(purrr) df_list_fixed <- imap(df_list, function(current_df, df_name) { current_df$year <- substring(df_name, 7, 10) current_df })
结果验证
运行以下代码可以核对结果是否符合预期:
# 查看第一个数据框的year列 df_list_fixed[[1]]$year # 输出: [1] "1990" "1990" "1990" # 查看第二个数据框的year列 df_list_fixed[[2]]$year # 输出: [1] "1991" "1991" "1991" # 查看第三个数据框的year列 df_list_fixed[[3]]$year # 输出: [1] "1992" "1992" "1992"
内容的提问来源于stack exchange,提问作者Diego Brizuela
相关产品推荐
相关产品推荐

