【问题标题】:Merging a bunch of csv files into one with headers将一堆 csv 文件合并为一个带有标题的文件
【发布时间】:2015-10-29 21:42:12
【问题描述】:

我有几个 csv 文件我想合并为一个列表,然后输出为一个合并的 csv。假设这些文件被称为file1.csv、file2.csv、file3.csv等……

file1.csv     # example of what each might look like
V1 V2 V3 V4
12 12 13 15
14 12 56 23

如何创建这些 csv 的列表,以便我可以输出合并的 csv,该 csv 将标题作为文件名,将顶部的列名作为 cmets?所以一个在 Excel 中看起来像这样的 csv:

# 1: V1
# 2: V2
# 3: V3
# 4: V4

file1.csv
12 12 13 15
14 12 56 23

file2.csv
12 12 13 15
14 12 56 23

file3.csv
12 12 13 15
14 12 56 23

我正在尝试在双 for 循环中使用 list 函数将这些 csv 合并在一起,将每个列表写入一个变量,并将每个变量写入一个表输出。但是这并没有按预期工作。

# finding the correct files in the directory
files <- dir("test files/shortened")
files_filter <- files[grepl("*\\.csv", files)]
levels <- unique(gsub( "-.*$", "", files_filter))

# merging
for(i in 1:length(levels)){
  level_specific <- files_filter[grepl(levels[i], files_filter)]
  bindme
  for(j in 1:length(level_specific)){
    bindme2 <- read.csv(paste("test files/shortened/",level_specific[j],sep=""))
    bindme <- list(bindme,bindme2)
    assign(levels[i],bindme)
  }
  write.table(levels[i],file = paste(levels[i],"-output.csv",sep=""),sep=",")
}

【问题讨论】:

  • 如果所有文件都具有相同的结构,您可以使用data.table 包中的rbindlist
  • 我应该如何使用 rbindlist 和 for 循环?我正在考虑将它放在 write.table 行之前的第一个 for 循环中,但是我不知道如何调用由第二个 for 循环生成的每个 data.table。

标签: r list csv merge


【解决方案1】:

修改这个例子。如果我正确理解了您的问题,它将对您有所帮助。

# get the names of the csv files in your current directory
    file_names = list.files(pattern = "[.]csv$")  

# for every name you found go and read the csv with that name 
# (this creates a list of files)
    import_files = lapply(file_names, read.csv)

# append those files one after the other (collapse list elements to one dataset) and save it as d
    d=do.call(rbind, import_files)

【讨论】:

    【解决方案2】:

    查看您的代码,我认为您不需要 for 循环。使用data.table 包,您可以按如下方式进行:

    filenames <- list.files(pattern="*.csv")
    files <- lapply(filenames, fread) # fread is the fast reading function from the data.table package
    merged_data <- rbindlist(files)
    write.csv(merged_data, file="merged_data_file.csv", row.names=FALSE)
    

    如果至少有一个csvs 设置了列名,则它们将用于生成的数据表中。


    考虑到您的代码,它可以大大改进。这个:

    files <- dir("test files/shortened")
    files_filter <- files[grepl("*\\.csv", files)]
    

    可以替换为:

    filenames <- list.files(pattern="*.csv")
    

    在你第一次调用bindme 时,它没有做任何事情。它是什么?一个列表?数据框?你可以使用类似的东西:

    bindme <- data.table() # or data.frame()
    

    另外,部分:

    write.table(levels[i],file = paste(levels[i],"-output.csv",sep=""),sep=",")
    

    将生成多个csv-文件,但您只需要一个合并文件。

    【讨论】:

      【解决方案3】:

      这会有帮助吗


      mergeMultipleFiles <- function(dirPath, nameRegex, outputFilename){
        filenames <- list.files(path=dirPath, pattern=nameRegex, full.names=TRUE, recursive=T)
        dataList <- lapply(filenames, read.csv, header=T, check.names=F)
        combinedData <- ldply(dataList, rbind)
        write.csv(combinedData, outputFilename)
      }
      

      ps:文件名有一个正则表达式。以防万一您只想合并文件的某些“模式”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        • 2016-03-16
        • 2019-10-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多