如何编写一个for循环以将多个csv文件读入R并子集数据以生成干净的ggplots数据帧?

时间:2019-02-25 19:38:10

标签: r loops subset gsub assign

我试图将多个csv读取到R中,然后通过使用'subset'函数删除不需要的列来对这些csvs进行子集化。我试图在r中设置一个for循环,可以将功能或计算添加到csvs列表中,以便稍后生成用于ggplots或stat分析的数据框。 (我目前安装了tidyverse,dplyr和ggplot2)。现在,我只想对csvs进行子集化,然后从子集化的数据中创建一个数据框。

我使用for循环通过设置工作目录,创建csvs列表,然后将它们读取到数据帧中来成功地将多个csvs读取到单独的数据帧中。当前,这为以原始文件名命名的每个csv输出一个数据帧:

filenames <- gsub("\\.csv$","", list.files(pattern="\\.csv$"))


for(i in filenames){
     assign(i, read.csv(paste(i, ".csv", sep="")))}

然后我意识到我想在将这些数据放入数据框之前先对它们进行子集化处理,以避免以后出现一些重复的代码。但是,每次尝试将子集函数添加到for循环时,我都会遇到错误。这是我目前拥有的:

for(i in filenames){
  read.csv(i)
  subset(i, select = c("names", "of columns", "I want"))
  assign(i, read.csv(paste(i, ".csv", sep="")))
}

我收到“没有这样的文件或目录错误”。我敢肯定我缺少一些明显的东西,因为我的R基础很差,但是任何帮助或建议做这项工作将不胜感激。子集函数过去对我有用,但是我不得不为每个数据框写一行新记录,并希望通过使用list和for循环或其他方法来避免这种情况。

谢谢

2 个答案:

答案 0 :(得分:0)

我最终使用@MrFlick建议,并完全使用lapply将所有文件合并到一个数据帧中并从那里进行子集,从而规避了循环。最终结果如下:

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

myfiles = do.call(rbind, lapply(filenames, function(x) read.csv(x, stringsAsFactors = FALSE)))

myfiles


myfiles.subset = subset(myfiles, select = c("names of", "columns", "I want")

答案 1 :(得分:0)

显然,所有csv文件的结构都相同,即列的编号和名称相同。因此,可以通过几种方法来改进MrFlickOP's own answer的建议:

  1. read.csv()函数读取所有列。因此,需要单独的子设置步骤以仅保留所需的列。 fread()包中的data.table函数具有一个select参数,可以读取仅读取文件中的所需列。
  2. rbindlist()do.call(rbind, ...)的缩写,但具有附加参数idcol。这将创建一个附加列,用于标识每行的来源。

创建数据帧列表

lapply(list.files(pattern = "\\.csv$"), data.table::fread, 
       select = c("names.of", "columns", "I.want"))
[[1]]
   names.of columns I.want
1:        1       2      3

[[2]]
   names.of columns I.want
1:       21      22     23

请注意,仅从文件中读取选定的列。

创建一个大数据框

library(data.table)
library(magrittr)   # piping used here to improve readability
lapply(list.files(pattern = "\\.csv$"), fread, select = c("names.of", "columns", "I.want")) %>% 
  rbindlist(idcol = TRUE)
   .id names.of columns I.want
1:   1        1       2      3
2:   2       21      22     23
3:   2       31      32     33

请注意,.id列给出了列表元素的序列号。

使用原始文件名创建一个大数据框

library(data.table)
library(magrittr)
filenames = list.files(pattern = "\\.csv$")
lapply(filenames, fread, select = c("names.of", "columns", "I.want")) %>% 
  set_names(filenames) %>% 
  rbindlist(idcol = "origin")
      origin names.of columns I.want
1: test1.csv        1       2      3
2: test2.csv       21      22     23
3: test2.csv       31      32     33

此处,set_names()包中的magrittr用于命名列表元素。 然后,rbindlist()将列表元素的名称用于id列。

样本数据

如果已创建两个文件。

test1.csv包含一行和四列:

"names.of", "columns", "I.want", "useless.column"
1, 2, 3, 4

test2.csv包含两行和五列:

"names.of", "columns", "I.want", "useless.column", "another.useless.column"
21, 22, 23, 24, 25
31, 32, 33, 34, 35

请注意,我已经修改了列名以确保它们在语法上是有效的变量名。