我有大量的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
答案 0 :(得分:23)
你已经完成了所有艰苦的工作。通过相当小的修改,这应该是直截了当的。
逻辑是:
以下内容应该有效:
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)
以下是使用rio中import_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")
这个创建源文件的新列,并合并它们。