2011-03-03 48 views
18

我有大量的csv文件,我想讀入R.Csvs中的所有列標題都是相同的。起初我以爲我需要創建一個基於文件名列表的循環,但搜索後我發現了一個更快的方法。這讀入並正確地結合了所有的csvs(據我所知)。將CSV導入到R時如何使用CSV的名稱生成列?

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 

回答

21

你已經做了所有的努力工作。經過一個相當小的修改,這應該是直截了當的。

的邏輯是:

  1. 創建一個小的輔助函數讀取單個CSV和與文件名添加一列。
  2. 在電話本llply輔助函數()

下面應該工作:

read_csv_filename <- function(filename){ 
    ret <- read.csv(filename) 
    ret$Source <- filename #EDIT 
    ret 
} 

import.list <- ldply(filenames, read_csv_filename) 

注意,我提出另一個小改進代碼:read.csv()返回的數據。幀 - 這意味着你可以使用ldply()而不是llply()。

+3

使用rep是可選的,'ret $ Source < - filename'也可以工作 – 2011-03-03 22:19:01

+0

@Karsten W,謝謝。我編輯了代碼以反映您的建議。 – Andrie 2011-03-03 23:30:43

+0

這可能是一個有點愚蠢的問題,但...當使用您的更改(ldply())時,數據將被重新格式化,所有列標題將轉換爲行標題,文件名(包含數字)將成爲列標題。有沒有解決的辦法?使用llply有沒有缺點? – Arndt 2011-03-04 14:56:36

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 
12

試試這個:

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

行名稱將註明出處和行號。

3

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) 

基本語法解決方案

我用格羅騰迪克的水溶液,並添加一行創建行名稱的列。就這麼簡單:

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

如果你只是想在文件名中的一部分,通過這樣的替換2號線:

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

這將使用1日從文件名作爲3個字符新列中的值。

0

下面是使用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參數來指定標識每個FIL的列的名稱e:

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的維護者。