我编写了以下函数来组合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
Run Code Online (Sandbox Code Playgroud)
我的错是什么?有人可以解释一下吗?
had*_*ley 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")
Run Code Online (Sandbox Code Playgroud)
请注意do.call
+ rbind
相对较慢.你可能会发现dplyr::bind_rows
或者data.table::rbindlist
要快得多.
要用他与莱昂内尔·亨利(Lionel Henry)合着的最新purrr
库中的代码来更新维克姆教授的上述答案,请执行以下操作:
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(.))
Run Code Online (Sandbox Code Playgroud)
如果类型转换很不客气,您可以使用此选项将所有列强制为字符。
Tbl <-
list.files(pattern="*.csv") %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
Run Code Online (Sandbox Code Playgroud)
如果要进入子目录来构造文件列表以进行最终绑定,请确保包括路径名,并在列表中注册文件的全名。这将使绑定工作可以在当前目录之外进行。(完整路径名应像护照一样操作,以允许在目录“边界”之间移动。)
Tbl <-
list.files(path = "./subdirectory/",
pattern="*.csv",
full.names = T) %>%
map_df(~read_csv(., col_types = cols(.default = "c")))
Run Code Online (Sandbox Code Playgroud)
正如Wickham教授在这里所描述的(大约一半):
map_df(x, f)
实际上与内幕相同,do.call("rbind", lapply(x, f))
但效率更高。
感谢Jake Kaupp 在这里向我介绍map_df()。
这可以使用 tidyverse 中的 dplyr 和 purrr 非常简洁地完成。其中 x 是 csv 文件名称列表,您可以简单地使用:
bind_rows(map(x, read.csv))
Run Code Online (Sandbox Code Playgroud)
将 read.csv 映射到 x 会生成一个 dfs 列表,然后通过 bind_rows 巧妙地组合起来!