列出循环R中被覆盖的元素



我有一堆csv文件,我试图一次读取到R中,csv中的每个数据帧都成为列表的一个元素。循环在很大程度上起作用,但它们不断覆盖列表元素。因此,例如,如果我在前两个文件上循环,则列表[[1]]和列表[[2]]中的数据帧都将包含第二个文件的数据帧。

#function to open one group of files named with "cores"
open_csv_core<- function(year, orgtype){
file<- paste(year, "/coreco.core", year, orgtype, ".csv", sep = "")
df <- read.csv(file)
names(df) <- tolower(names(df))
df <- df[df$ntee1 %in% c("C","D"),]
df<- df[!(df$nteecc %in% c("D20","D40", "D50", "D60", "D61")),]
return(df)
}
#function to open one group of files named with "nccs"
open_csv_nccs<- function(year, orgtype){
file2<- paste(year, "/nccs.core", year, orgtype, ".csv", sep="")
df2 <- read.csv(file2)
names(df2) <- tolower(names(df2))
df2 <- df2[df2$ntee1 %in% c("C","D"),]
df2<- df2[!(df2$nteecc %in% c("D20","D40", "D50", "D60", "D61")),]
return(df2)
}
#############################################################################
yrpc<- list()
yrpf<- list()
yrco<- list()
fname<- vector()
file_yrs<- as.character(c(1989:2019))
for(i in 1:length(file_yrs)){

fname<- list.files(path = file_yrs[i], pattern = NULL)
#accessing files in a folder and assigning to the proper function to open them based on how the file is named  
for(j in 1:length(fname)){

if(grepl("pc.csv", fname[j])==T) { 

if(grepl("nccs", fname[j])==T){
a <- open_csv_nccs(file_yrs[j], "pc") 
yrpc[[paste0(file_yrs[i], "pc")]] <- a

} else {
b<- open_csv_core(file_yrs[j], "pc")
yrpc[[paste0(file_yrs[i], "pc")]] <- b
}

} else if (grepl("pf.csv", fname[j])==T){

if(grepl("nccs", fname[j])==T){
c <- open_csv_nccs(file_yrs[j], "pf")
yrpf[[paste0(file_yrs[i], "pf")]] <- c

} else {
d<- open_csv_core(file_yrs[j], "pf")
yrpf[[paste0(file_yrs[i], "pf")]] <- d
}

} else {

if(grepl("nccs", fname[j])==T){
e<- open_csv_nccs(file_yrs[j], "co")
yrco[[paste0(file_yrs[i], "co")]] <- e

} else {
f<- open_csv_core(file_yrs[j], "co")
yrco[[paste0(file_yrs[i], "co")]] <- f
}
}


}
}

实际上,两个csv读取函数的作用完全相同,除了路径不同之外。

如果你找到了一种方法,用抽象路径而不是相对路径列出你的文件路径(只是文件名),您不需要像可以。这可以通过list.files()中的full.names = TRUE实现。

第二点是,似乎从来没有来自同一年份和同一类型的a";nccs.core";除了"文件"之外;coreco.core";文件所以他们是相互的独家因此,没有必要用逻辑来区分这些情况,这简化了我们的代码。

第三点是,您只想按文件类型("pc"、"pf"、"co")和年份来分隔数据帧。

我不会为每种类型创建3个列表,而是创建一个res-ults列表,其中为每一种类型包含一个内部列表。

我会这样解决这个问题:

years <- c(1989:2019) 
path_to_type <- function(path) gsub(".*(pc|pf|co)\.csv", "\1", path)
res <- list("pc" = list(),
"pf" = list(),
"co" = list())
lapply(years, function(year) {
files <- list.files(path = year, pattern = "\.csv", full.names = TRUE)
dfs <- lapply(files, function(path) {
print(path) # just to signal that the path is getting processed
df <- read.csv(path)
file_type <- path_to_type(path)
names(df) <- tolower(names(df))
df <- df[df$ntee1 %in% c("C", "D"), ]
df <- df[!(df$nteecc %in% c("D20", "D40", "D50", "D60", "D61")), ]
res[[file_type]][[year]] <- df
})
}) 

现在,您可以按file_type和年份从结果列表中调用例如:

res[["co"]][[1995]]
res[["pf"]][[2018]]

等等。

实际上,在这种情况下lapply()调用的结果是不感兴趣。只是res的内容。。。(结果列表)。

似乎在for(j in 1:length(fname)){...中创建了4个变量abcd中的一个。您正在重用这些变量名,因此它们会被覆盖。

";正确的";实现这一点的方法是使用CCD_ 10来代替CCD_。将文件列表和所需函数(如open_csv_core等)传递给lapply,返回的返回值是结果列表。

相关内容

  • 没有找到相关文章

最新更新