将CSV导入R时如何生成包含CSV名称的列?

时间:2011-03-03 21:08:44

标签: r

我有大量的csv文件要读入R.所有csvs中的列标题都是相同的。起初我以为我需要根据文件名列表创建一个循环,但在搜索之后我发现了一种更快的方法。这将正确读入并组合所有csvs(据我所知)。

filenames <- list.files(path = ".", pattern = NULL, all.files = FALSE, full.names = FALSE, recursive = FALSE, ignore.case = FALSE)

library(plyr)
import.list <- llply(filenames, read.csv)

combined <- do.call("rbind", import.list)

唯一的问题是我想知道特定行数据来自哪个csv。我想要一个标有“source”的列,其中包含特定行来自的csv的名称。所以例如,如果csv被称为Chicago_IL.csv,当数据进入R时,行看起来像这样:

> City    State   Market  etc Source  
> Burbank IL      Western etc Chicago_IL

6 个答案:

答案 0 :(得分:23)

你已经完成了所有艰苦的工作。通过相当小的修改,这应该是直截了当的。

逻辑是:

  1. 创建一个小助手函数,该函数读取单个csv并添加一个带有文件名的列。
  2. 在llply()
  3. 中调用此辅助函数

    以下内容应该有效:

    read_csv_filename <- function(filename){
        ret <- read.csv(filename)
        ret$Source <- filename #EDIT
        ret
    }
    
    import.list <- ldply(filenames, read_csv_filename)
    

    请注意,我已经对您的代码提出了另一个小改进:read.csv()返回一个data.frame - 这意味着您可以使用ldply()而不是llply()。

答案 1 :(得分:13)

试试这个:

do.call("rbind", sapply(filenames, read.csv, simplify = FALSE))

行名称将指示源和行号。

答案 2 :(得分:4)

data.table解决方案

更新:这是一个完整的data.table解决方案,使用keep.rownames。假设您的所有CSV都在一个文件夹中:

library(data.table)
my.path <- "C:/some/path/to/your/folder" #set the path
filenames <- paste(my.path, list.files(path=my.path), sep="/") #list of files

#this will create a rn column with the path in it
my.dt<- data.table(do.call("rbind", sapply(filenames, read.csv,     
                  sep=";")), keep.rownames = T)

基本语法解决方案

我使用了Grothendieck的解决方案并添加了一行来从行名创建一个列。就这么简单:

something <- do.call("rbind", sapply(filenames, read.csv, sep=";", simplify = FALSE)) 
something$mycolumn <- row.names(something)

如果您只想要文件名的一部分,请用以下内容替换第二行:

something$mycolumn <- substring(row.names(something),1,3)

这将使用文件名中的前3个字符作为新列中的值。

答案 3 :(得分:3)

以下是使用rioimport_list()函数的解决方案,该函数专为此目的而设计。

# setup some example files to import
rio::export(mtcars, "mtcars1.csv")
rio::export(mtcars, "mtcars2.csv")
rio::export(mtcars, "mtcars3.csv")

import_list()的默认行为是获取数据框列表:

str(rio::import_list(dir(pattern = "mtcars")), 1)
## List of 3
##  $ :'data.frame':       32 obs. of  11 variables:
##  $ :'data.frame':       32 obs. of  11 variables:
##  $ :'data.frame':       32 obs. of  11 variables:

但您可以使用rbind参数来构建单个数据框(请注意最后的_file列):

str(rio::import_list(dir(pattern = "mtcars"), rbind = TRUE))
## 'data.frame':   96 obs. of  12 variables:
##  $ mpg  : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl  : int  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp : num  160 160 108 258 360 ...
##  $ hp   : int  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat : num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt   : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec : num  16.5 17 18.6 19.4 17 ...
##  $ vs   : int  0 0 1 1 0 1 0 1 1 1 ...
##  $ am   : int  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear : int  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb : int  4 4 1 1 2 1 4 2 2 4 ...
##  $ _file: chr  "mtcars1.csv" "mtcars1.csv" "mtcars1.csv" "mtcars1.csv" ...

rbind_label参数指定标识每个文件的列的名称:

str(rio::import_list(dir(pattern = "mtcars"), rbind = TRUE, rbind_label = "source"))
## 'data.frame':   96 obs. of  12 variables:
##  $ mpg   : num  21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
##  $ cyl   : int  6 6 4 6 8 6 8 4 4 6 ...
##  $ disp  : num  160 160 108 258 360 ...
##  $ hp    : int  110 110 93 110 175 105 245 62 95 123 ...
##  $ drat  : num  3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
##  $ wt    : num  2.62 2.88 2.32 3.21 3.44 ...
##  $ qsec  : num  16.5 17 18.6 19.4 17 ...
##  $ vs    : int  0 0 1 1 0 1 0 1 1 1 ...
##  $ am    : int  1 1 1 0 0 0 0 0 0 0 ...
##  $ gear  : int  4 4 4 3 3 3 3 4 4 4 ...
##  $ carb  : int  4 4 1 1 2 1 4 2 2 4 ...
##  $ source: chr  "mtcars1.csv" "mtcars1.csv" "mtcars1.csv" "mtcars1.csv" ...

完全披露:我是rio的维护者。

答案 4 :(得分:1)

有点凌乱,但有效:

filenames <- c("foo.csv","bar.csv")
import.list <- list(matrix(,4,4),matrix(6,6))

source <- unlist(sapply(1:length(filenames),function(i)rep(gsub(".csv","",filenames[i]),nrow(import.list[[i]]))))

source
[1] "foo" "foo" "foo" "foo" "bar" "bar" "bar" "bar" "bar" "bar"

combined$source <- source

答案 5 :(得分:0)

发现这个为我工作,它创建新列并合并整个文件夹csv文件。

使用setNames():

file.list <- list.files(pattern = '*.csv')
file.list <- setNames(file.list, file.list)

df.list <- lapply(file.list, read_csv)
df.list <- Map(function(df, name) {
  df$issue <- name
  df
}, df.list, names(df.list))
df <- rbindlist(df.list,use.names = TRUE, fill = TRUE, idcol = "Issue")

这个创建源文件的新列,并合并它们。