在r循环中将多个csv文件组合在一起

问题描述

我有一个包含许多csv文件文件夹。它们都是按图片构造的

enter image description here

我有兴趣计算变量“ 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,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)

每次尝试更改代码时都会遇到不同的错误,所以我不确定如何解决此问题。

解决方法

有以下几种方法可以对每个文件中的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,header = TRUE)
  mydata %>%
    count(Type) %>%
    mutate(filename = basename(x))
})
,

这是一个满足您需求的并行版本。 您可能需要安装 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 上进行了测试,与常规循环相比具有巨大的加速。