我编写了以下函数来组合300个.csv文件。我的目录名是“specdata”。我已经完成了以下执行步骤,
x <- function(directory) {
dir <- directory
data_dir <- paste(getwd(),dir,sep = "/")
files <- list.files(data_dir,pattern = '\\.csv')
tables <- lapply(paste(data_dir,files,sep = "/"), read.csv, header = TRUE)
pollutantmean <- do.call(rbind , tables)
}
# Step 2: call the function
x("specdata")
# Step 3: inspect results
head(pollutantmean)
Error in head(pollutantmean) : object 'pollutantmean' not found
我的错误是什么?有人可以解释一下吗?
答案 0 :(得分:45)
你的功能中有很多不必要的代码。您可以将其简化为:
load_data <- function(path) {
files <- dir(path, pattern = '\\.csv', full.names = TRUE)
tables <- lapply(files, read.csv)
do.call(rbind, tables)
}
pollutantmean <- load_data("specdata")
请注意do.call
+ rbind
相对较慢。您可能会发现dplyr::bind_rows
或data.table::rbindlist
要快得多。
答案 1 :(得分:4)
使用与Lionel Henry合着的最新purrr
library代码更新Wickham教授的答案:
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(.))
如果类型转换是厚脸皮的,你可以强制所有列都是这个字符。
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
如果您想深入子目录来构建最终要绑定的文件列表,那么请确保包含路径名,以及在列表中注册文件及其全名。这将允许绑定工作在当前目录之外进行。 (将完整的路径名视为像护照一样运行,以允许在目录'边界'之间移动。)
Tbl <-
list.files(path = "./subdirectory/",
pattern="*.csv",
full.names = T) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
正如Wickham教授所描述的那样here(大约一半):
map_df(x, f)
实际上与do.call("rbind", lapply(x, f))
相同,但引导效率更高。
感谢Jake Kaupp向我介绍map_df()here。
答案 2 :(得分:1)
```{r echo = FALSE, warning = FALSE, message = FALSE}
setwd("~/Data/R/BacklogReporting/data/PastDue/global/") ## where file are located
path = "~/Data/R/BacklogReporting/data/PastDue/global/"
out.file <- ""
file.names <- dir(path, pattern = ".csv")
for(i in 1:length(file.names)){
file <- read.csv(file.names[i], header = TRUE, stringsAsFactors = FALSE)
out.file <- rbind(out.file, file)
}
write.csv(out.file, file = "~/Data/R/BacklogReporting/data/PastDue/global/global_stacked/past_due_global_stacked.csv", row.names = FALSE) ## directory to write stacked file to
past_due_global_stacked <- read.csv("C:/Users/E550143/Documents/Data/R/BacklogReporting/data/PastDue/global/global_stacked/past_due_global_stacked.csv", stringsAsFactors = FALSE)
files <- list.files(pattern = "\\.csv$") %>% t() %>% paste(collapse = ", ")
```
答案 3 :(得分:1)
这可以用tidyverse的dplyr和purrr非常简洁地完成。其中x是csv文件名称的列表,您只需使用:
bind_rows(map(x, read.csv))
将read.csv映射到x会产生一个dfs列表,bind_rows然后整齐地组合!
答案 4 :(得分:0)
如果您的csv文件位于另一个目录中,则可以使用以下内容:
readFilesInDirectory <- function(directory, pattern){
files <- list.files(path = directory,pattern = pattern)
for (f in files){
file <- paste(directory,files, sep ="")
temp <- lapply(file, fread, sep=",")
data <- rbindlist( temp )
}
return(data)
}
答案 5 :(得分:-1)
在您当前的函数中,pollutantmean
仅在函数x
的范围内可用。将您的功能修改为此
x <- function(directory) {
dir <- directory
data_dir <- paste(getwd(),dir,sep = "/")
files <- list.files(data_dir,pattern = '\\.csv')
tables <- lapply(paste(data_dir,files,sep = "/"), read.csv, header = TRUE)
assign('pollutantmean',do.call(rbind , tables))
}
assign
应将do.call(rbind, tables)
的结果放入全球环境中名为pollutantmean
的变量中。