我有一堆 csv 檔案,我試圖一次將它們全部讀入 R,來自 csv 的每個資料幀都成為串列的一個元素。回圈在很大程度上起作用,但它們不斷覆寫串列元素。因此,例如,如果我遍歷前 2 個檔案,list[[1]] 和 list[[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
}
}
}
}
uj5u.com熱心網友回復:
實際上,您的兩個 csv 讀取函式的功能完全相同,只是路徑不同。
如果您找到一種使用抽象路徑而不是相對路徑(僅檔案名)列出檔案的方法,則無需像以前那樣重建路徑。這可以通過full.names = TRUEin實作list.files()。
第二點是,除了“coreco.core”檔案之外,似乎從來沒有來自同一年和同一型別的“nccs.core”檔案。所以它們是相互排斥的。因此,沒有必要的邏輯來區分這些情況,這簡化了我們的代碼。
第三點是,您只想按檔案型別(“pc”、“pf”、“co”)和年份來分隔資料幀。
我不會為每種型別創建 3 個串列,而是創建一個結果串列,其中包含每種型別的內部串列。
我會這樣解決這個問題:
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 和 year 從結果串列中呼叫,例如:
res[["co"]][[1995]]
res[["pf"]][[2018]]
等等。
實際上,lapply()這種情況下的呼叫結果并不有趣。只是res...的內容(結果串列)。
uj5u.com熱心網友回復:
似乎for(j in 1:length(fname)){...您正在創建 4 個變數a、b或. 而且您正在重用這些變數名,因此它們會被覆寫。cd
執行此操作的“正確”方法是lapply代替for回圈使用。將檔案串列和所需的函式(即open_csv_core等)傳遞給lapply,您得到的回傳值是結果串列。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/478311.html
