如何解决lapply中按名称传递数据框时无法获取真实名称的问题?
解决方法
核心问题是lapply无法传递原数据框的名称,改用purrr::imap(tidyverse工具)可以同时获取数据框和对应的名称,前提是你的数据框列表是命名列表。
步骤1:确保数据框列表是命名的
如果dfs还不是命名列表,先给它命名:
# 示例1:批量获取全局环境中符合规则的数据框并生成命名列表 dfs <- mget(ls(pattern = "^df_")) # 示例2:手动指定名称 dfs <- list(df_2021 = df_2021, df_2022 = df_2022)
步骤2:修正函数并调用
方法一:定义独立函数
library(tidyverse) query_loop <- function(df, df_name){ # 截取名称子串(根据你的原名称结构调整位置参数) year_sub <- substring(df_name, 14, 15) # 生成目标变量名 cpt_name <- paste0("cpt_20", year_sub) # 过滤数据 filtered_df <- filter(df, CPT == "12345") # 将结果保存到全局环境(可选操作) assign(cpt_name, filtered_df, envir = .GlobalEnv) # 写入txt文件 write.table(filtered_df, file = paste0(cpt_name, ".txt"), row.names = FALSE, sep = "\t") # 返回过滤后的数据,方便后续处理 return(filtered_df) } # 用imap遍历,同时传递数据框和对应名称 dfs1 <- imap(dfs, query_loop)
方法二:用匿名函数简化
library(tidyverse) dfs1 <- imap(dfs, function(df, df_name){ year_sub <- substring(df_name, 14, 15) cpt_name <- paste0("cpt_20", year_sub) filtered_df <- df %>% filter(CPT == "12345") assign(cpt_name, filtered_df, envir = .GlobalEnv) write.table(filtered_df, paste0(cpt_name, ".txt"), row.names = F, sep = "\t") filtered_df })
原代码的错误点
lapply仅传递列表元素,无法携带原数据框名称,导致deparse(substitute(df))返回临时索引X[[i]]write.table(cpt, ...)错误传入变量名字符串,而非过滤后的数据集,会导致文件内容为字符串而非数据assign未指定全局环境,生成的变量仅存在于函数内部,全局环境无法访问
内容的提问来源于stack exchange,提问作者grapeporcupine
相关产品推荐
相关产品推荐

