【问题标题】:R: how to extract column in multiple csv and then write multiple csv in one folderR:如何在多个csv中提取列,然后在一个文件夹中写入多个csv
【发布时间】:2020-09-04 00:58:45
【问题描述】:

我有一个包含多个 csv 的文件夹(文件夹 1):“x.csv”、“y.csv”、“z.csv”... 我想提取每个文件的第三列,然后在新文件夹(文件夹 2)中写入新的 csv 文件。因此,文件夹 2 必须包含“x.csv”、“y.csv”、“z.csv”...(但只有第 3 列)。

我试过了:

dfiles <- list.files(pattern =".csv") #if you want to read all the files in working directory
lst2 <- lapply(dfiles, function(x) (read.csv(x, header=FALSE)[,3]))

但是我收到了这个错误:

 Error in `[.data.frame`(read.csv(x, header = FALSE), , 3) : 
  undefined columns selected 

另外,我不知道怎么写多个csv。

但是,如果我对一个文件执行此操作,它可以正常工作,尽管输出位于同一文件夹中:

essai <-read.csv("x.csv", header = FALSE, sep = ",")[,3]
write.csv (essai, file = "x.csv")

任何帮助将不胜感激。

【问题讨论】:

    标签: r loops csv


    【解决方案1】:

    所以我会这样做。可能有更好,更有效的方法,但它仍然应该工作得很好。

    setwd("~/stackexchange") #set your main folder. Best way to do this is actually the here() package. But that's another topic.
    
    
    library(tools) #for file extension tinkering
    folder1 <- "folder1" #your original folder
    folder2 <- "folder2" #your new folder
    
    #I setup a function and loop over it with lapply.
    write_to <- function(file.name){
    file.name <-  paste0(tools::file_path_sans_ext(basename(file.name)), ".csv")
    essai <-read.csv(paste(folder1, file.name, sep = "/"), header = FALSE, sep = ",")[,3]
    write.csv(essai, file = paste(folder2, file.name, sep="/")) 
    }
    
    
    # get file names from folder 1
    dfiles <- list.files(path=folder1, pattern ="*.csv") #if you want to read all the csv files in folder1 directory
    
    lapply(X = paste(folder1, dfiles, sep="/"), write_to)
    

    玩得开心! 顺便说一句:如果你有很多文件,你可以使用 data.table::freaddata.table::fwrite 大大提高 csv 读/写速度。

    【讨论】:

    • 谢谢!我不明白为什么,但是当我在您建议的功能中使用 read.csv 时(或下面的 lapply),它似乎无法正常工作。我收到带有“选择的未定义列”的错误消息...
    • 我认为下面的Ronak's 答案可能会有所帮助。您是否检查过所有 csv 文件是否确实有第三列?
    • 好的。在不知道文件结构的情况下,我不确定是否能提供更多帮助。我在我的机器上尝试了 2 个随机 csv 文件,效果很好。两个建议(1)尝试使用 1-2 个随机 csv 文件,看看它是否有效。 (2) 你是否必须跳过一些变量,例如你的列名在第 1 行吗?
    • 我终于解决了这个问题,并设法用你的脚本来解决。谢谢。
    【解决方案2】:

    首先,从错误消息看来,某些 csv 文件的列数少于 3。检查您是否正在阅读正确的文件,以及它们是否都应该至少有 3 列。

    完成后,您可以使用以下代码读取 csv 文件,选择第 3 列并将 csv 文件写入 'folder2'

    lapply(dfiles, function(x) {
       df <- read.csv(x, header = FALSE)
       write.csv(subset(df, select = 3), paste0('folder2/', x), row.names = FALSE)
    })
    

    【讨论】:

    • 非常感谢。我认为它可以工作,但我仍然有错误消息。我正在阅读正确的文件,它们都有 3 列...为了更好地理解问题,我只在文件夹中保留了我的第一个文件,看看会发生什么。首先,我分别做了一些事情:read.csv(我得到了一个有 3 列的 df),然后是 write.csv 和子集(我得到了我想要的)。然后我尝试了 lapply,我收到了错误消息......这让我发疯了,因为我不明白为什么......
    • @AdeLac74 你能运行sapply(dfiles, function(x) nrow(read.csv(x, header = FALSE))) 并查看行数。有没有小于 3 的值?
    • 当我这样做时,我得到的只是行数。我认为 read.csv 函数有问题。如果我这样做(我的文件夹仍然只包含第一个文件):df &lt;-lapply(dfiles, function(x) { read.csv(x, header = FALSE) }) 我得到一个 1df 列表,只有 1 个变量。
    • 对不起,我们需要检查列数。改为sapply(dfiles, function(x) ncol(read.csv(x, header = FALSE))) 并检查是否有小于3 的数据。which(sapply(dfiles, function(x) ncol(read.csv(x, header = FALSE))) &lt;= 2) 的输出是什么?
    • 好的,谢谢;只有一列,第二行的输出是:01A_CHANI_lab.csv 1 (即我的文件名,当然还有我的文件号)
    【解决方案3】:

    对于这个问题的“写”部分,我在 purrr 中使用了 map2() 有一些运气。我不确定这是最优雅的解决方案,但它就是这样:

    listofessais # this is your .csv files together as a named list of tbls
    map2(listofessais, names(listofessais), ~write_csv(.x, glue("FilePath/{.y}.csv"))
    

    这应该会为您提供在该文件夹中导出的所有 .csv 文件,并使用列表中给出的相同名称命名。

    【讨论】:

      猜你喜欢
      • 2022-11-03
      • 2021-06-24
      • 2018-01-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多