19

我编写了以下函数来组合 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

我的错误是什么?谁能解释一下?

4

6 回答 6

48

您的函数中有很多不必要的代码。您可以将其简化为:

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_rowsdata.table::rbindlist要快得多。

于 2014-04-21T13:04:12.260 回答
11

用他与 Lionel Henry 合着的最新purrr中的代码更新 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 教授在这里描述的那样(大约一半):

map_df(x, f)实际上是相同的,do.call("rbind", lapply(x, f))但在引擎盖下效率更高。

感谢 Jake Kaupp 在这里向我介绍 map_df() 。

于 2017-02-14T04:29:36.647 回答
5

这可以使用 tidyverse 中的 dplyr 和 purrr 非常简洁地完成。其中 x 是 csv 文件的名称列表,您可以简单地使用:

bind_rows(map(x, read.csv))

将 read.csv 映射到 x 会生成一个 dfs 列表,bind_rows 然后巧妙地组合!

于 2018-05-31T12:43:45.973 回答
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 = ", ")
```
于 2016-10-16T02:11:40.677 回答
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)
}
于 2019-03-13T18:15:29.930 回答
-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

于 2014-04-21T03:28:10.503 回答