【问题标题】:Combining multiple csv files together in an r loop在 r 循环中将多个 csv 文件组合在一起
【发布时间】:2020-12-27 17:02:44
【问题描述】:

我有一个文件夹,里面有很多 csv 文件。它们都是按图片结构的

我有兴趣计算变量“Type”下的数字,并得到一个输出,告诉我有两个数字 7、两个数字 9、两个 1 等等。我想对我文件夹中的 csv 文件执行此操作,将来自不同文件的输出绑定在一起会很棒(带有一个标识符到从中提取输出的原始文件)。 到目前为止,我设法使用以下代码对单个文件执行此操作:

mydata <- read.csv("1_data.csv", skip=1, header = T)
df <- data.frame(table(mydata$Type))

但是,我尝试编写一个循环并卡住了。这是我正在使用的代码:

files = list.files(pattern = "*.csv")

for (i in files) {
  id <- substr(i, 1, 5)
  mydata <- read.csv (i, skip=1, header = T)
  datatobind <- data.frame(table(mydata$Type))
  datatobind["id"] <- as.numeric(id)
  data <- rbind(data, datatobind)
}
do.call (rbind, data)

write.csv(data, file='final.csv', row.names=FALSE)

每次我尝试更改代码时都会收到不同的错误,所以我不知道如何解决这个问题。

【问题讨论】:

  • 尝试先使用L &lt;- lapply( files, data.table::fread, skip = 1 )之类的方式将文件读取到列表中,然后使用DT &lt;- data.table::rbindlist(L, use.names = TRUE, fill = TRUE )对列表进行行绑定
  • 您好,感谢您的回复。不幸的是,我有兴趣将输出合并在一起(所以在我计算了“类型”变量下的数字之后)。这是因为我正在尝试识别错误并且我需要查看错误在哪个文件中。我想到的绑定输出 CSV 文件应包含带有文件名的标题或空白行以使其清晰。 - 但这是在我弄清楚如何循环之后

标签: r loops csv rbind


【解决方案1】:

这里有几种方法可以计算每个文件中的 Type 列,添加一个带有文件名的新列并将输出绑定在一起。

使用基础 R:

files = list.files(pattern = "*.csv", full.names = TRUE)

new_data <- do.call(rbind, lapply(files, function(x) {
                  mydata <- read.csv(x, skip=1, header = TRUE)
                  transform(as.data.frame(table(mydata$Type)), 
                            filename = basename(x))
            }))

tidyverse

library(dplyr)

new_data <- purrr::map_df(files, function(x) {
  mydata <- read.csv(x, skip=1, header = TRUE)
  mydata %>%
    count(Type) %>%
    mutate(filename = basename(x))
})

【讨论】:

    【解决方案2】:

    这里有一个适合您需要的并行版本。 您可能需要安装 doSNOWparallel 软件包:

    library(doSNOW)
    library(parallel)
    
    setwd("path/to/folder")
    
    all_files = list.files(pattern = "\\.csv$")
    num_files = length(all_files)
    
    cl <- makeCluster(min(num_files, floor(detectCores()*0.9)), outfile = "")
    registerDoSNOW(cl)
    dataset <- foreach(i=1:num_files, .combine='rbind') %dopar% 
    {
      read.csv(all_files[i], header=TRUE)
    }
    stopCluster(cl)
    registerDoSEQ()
    
    write.csv(dataset, file='final.csv', row.names=FALSE)
    

    在 Windows 10 x64 上测试,与常规循环相比具有巨大的加速。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 2012-04-29
      • 1970-01-01
      • 1970-01-01
      • 2021-07-11
      • 2021-08-17
      相关资源
      最近更新 更多