2011-12-07 521 views
3

我有3個文件與3個變量:日期,ID和價格。我想按日期來合併它們,因此如果我當前的文件是:合併.csv文件與R

date  ID Price 
01/01/10 A 1 
01/02/10 A 1.02 
01/02/10 A 0.99 
... 
... 

我想獲得一個合併的文件,看起來像下面的一個ID分別爲A,B和C(鐠價格面議) :

date  Pr.A Pr.B Pr.C  
01/01/10 1  NA NA 
01/02/10 1.02 1.2 NA 
01/03/10 0.99 1.3 1 
01/04/10 NA  1.23 2 
01/05/10 NA  NA 3 

請注意,某些日期沒有價格,因此在這種情況下是NA。

我目前的方法可行,但我覺得有點笨拙。

setwd('~where you put the files') 
library(plyr) 
listnames = list.files(pattern='.csv') 
pp1 = ldply(listnames,read.csv,header=T) #put all the files in a data.frame 

names(pp1)=c('date','ID','price') 
pp1$date = as.Date(pp1$date,format='%m/%d/%Y') 

# Reshape data frame so it gets organized by date 
pp1=reshape(pp1,timevar='ID',idvar='date',direction='wide') 

有什麼更好的方法可以想到嗎?

+1

轉到http://stackoverflow.com/questions/1562124/merge-many-data-frames-from-csv-files –

+0

一個注意 - 鏈接文件' 「a1.csv」'包含了幾個額外的用逗號分隔的行沒有數據。我手動刪除它們,而不是在那裏做R代碼。 –

+0

我其實覺得你在'reshape'這裏做了什麼是一個很好的選擇。 – joran

回答

4

看起來像Reduce()工作:

# Read the files in to a single list, removing unwanted second column from each. 
dataDir <- "example" 
fNames <- dir(dataDir) 
dataList <- lapply(file.path(dataDir, fNames), 
        function(X) {read.csv(X, header=TRUE)[-2]}) 

# Merge them     
out <- Reduce(function(x,y) merge(x,y, by=1, all=TRUE), dataList) 

# Construct column names 
names(out)[-1] <- paste("Pr.", toupper(sub("1.csv", "", fNames)), sep="") 
out 
#  date Pr.A Pr.B Pr.C 
# 1 1/1/2010 1.00 NA NA 
# 2 1/2/2010 1.02 1.20 NA 
# 3 1/3/2010 0.99 1.30 1 
# 4 1/4/2010 NA 1.23 2 
# 5 1/5/2010 NA NA 3 

其實,你的方法看起來只有精細到我,但我可以看到寧願在通話的簡單性和語法的透明度Reduce

+0

如何降低速度方面的表現? –

+0

@PaulHiemstra:我的猜測並不好(因爲它可能會(??)爲每個合併操作創建一個新的data.frame)。我不是很清楚,但我會說如果問題的速度有問題,我不會建議'減少'。 –

+0

使用Reduce的有趣選擇。現在沒有R有這種內置的函數式編程方法。 – LouisChiffre

1

我沒有訪問這些文件,我在企業防火牆後面。一旦你建立了data.frame,我會使用cast方法。

res = cast(pp1,date~ID,value="Price",mean)