R语言for循环动态分配CSV至对象报错,求解决方法
R语言批量导入月度CSV并生成月份命名dataframe的问题解决
问题背景与错误
需要批量导入2023年12个月的CSV账单,每个文件对应一个Jan、Feb这类月份命名的dataframe,同时过滤掉内部转账和金额非负的记录。运行原代码时出现以下错误和警告:
错误信息
Error in UseMethod("filter") :
no applicable method for 'filter' applied to an object of class "list"
警告信息
In Months[i] <- read_csv(FileP, show_col_types = F) :
number of items to replace is not a multiple of replacement length
原代码如下:
library(readr) library(dplyr) Months <- c(Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec) fileN <- c("2023-01-01", "2023-02-01", "2023-03-01", "2023-04-01", "2023-05-01", "2023-06-01", "2023-07-01", "2023-08-01", "2023-09-01", "2023-10-01", "2023-11-01", "2023-12-01") dir = "/R/" #I have anonymised this directory for privacy reasons for(i in 1:12){ FileP <- paste0(dir,fileN[i],".csv") Months[i] <- read_csv(FileP, show_col_types = F) Months[i] <- Months[i] %>% filter( Months[i]$`Transaction Type` != "Internal Transfer" & Months[i]$Amount < 0) }
原代码问题分析
Months变量定义错误:c(Jan, Feb,...)里的Jan等变量未定义,R会视为缺失值;而且普通向量无法存储dataframe类型的元素,强行赋值会导致数据拆分,触发长度不匹配警告。filter调用错误:Months[i]作为列表元素,直接传给filter时,函数接收的是列表而非dataframe,因此报错找不到对应方法;同时filter内部重复引用Months[i]$属于冗余写法,管道已经将数据传入函数。
修正方案
方案1:用列表存储(推荐,便于批量操作)
这种方式将所有月度数据存入一个列表,通过月份名称作为键来访问,比分散的变量更易于管理:
library(readr) library(dplyr) # 定义月份名称和对应的文件名 month_names <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") file_names <- c("2023-01-01", "2023-02-01", "2023-03-01", "2023-04-01", "2023-05-01", "2023-06-01", "2023-07-01", "2023-08-01", "2023-09-01", "2023-10-01", "2023-11-01", "2023-12-01") dir_path <- "/R/" # 替换为你的实际文件目录 # 创建空列表用于存储处理后的月度数据 month_data_list <- list() for(i in 1:12){ # 拼接完整文件路径 full_path <- paste0(dir_path, file_names[i], ".csv") # 读取CSV并过滤数据 processed_df <- read_csv(full_path, show_col_types = FALSE) %>% filter(`Transaction Type` != "Internal Transfer", Amount < 0) # 将处理后的dataframe存入列表,用月份名称作为键 month_data_list[[month_names[i]]] <- processed_df } # 访问示例:获取1月数据 # month_data_list$Jan # 或者 month_data_list[["Jan"]]
方案2:创建独立的月份命名变量
如果确实需要生成Jan、Feb这类独立的全局变量,可以用assign函数实现:
library(readr) library(dplyr) month_names <- c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") file_names <- c("2023-01-01", "2023-02-01", "2023-03-01", "2023-04-01", "2023-05-01", "2023-06-01", "2023-07-01", "2023-08-01", "2023-09-01", "2023-10-01", "2023-11-01", "2023-12-01") dir_path <- "/R/" for(i in 1:12){ full_path <- paste0(dir_path, file_names[i], ".csv") processed_df <- read_csv(full_path, show_col_types = FALSE) %>% filter(`Transaction Type` != "Internal Transfer", Amount < 0) # 将dataframe赋值给全局环境中以月份命名的变量 assign(month_names[i], processed_df, envir = .GlobalEnv) } # 直接通过变量名访问:比如输入Jan即可查看1月的过滤后数据
关键修正点说明
- 将未定义的
Jan等变量替换为字符串类型的月份名称向量,避免未定义错误。 - 用列表存储dataframe(推荐)或
assign创建变量,解决普通向量无法存储dataframe的问题,消除长度不匹配警告。 - 利用dplyr管道的特性,在
filter中直接引用列名,无需重复指定数据对象,同时确保传入filter的是dataframe而非列表。
内容的提问来源于stack exchange,提问作者LWiz
相关产品推荐
相关产品推荐

