2017-05-24 129 views
0

我有幾個csv文件,每個文件大約有50,000行。所有文件都有名爲idPositionX的列。我只想在id和PositionX相同的情況下綁定它們。如果不相同,只需放一個NA。我使用如下:合併大型csv文件

datlist<-list(Cfour,Cfive,Csix,Cseven,Cten,Ctwelve,Cthirteen,Cfourteen,Cfifteen,Csixteen,Cseventeen,Cnineteen,Ctwoone,Ctwofour,Ctwosix,Ctwonine,Cthreethree,Cthreeseven,Cfourty) 
ss<-Reduce(function(df1,df2) merge(df1,df2,by=c("id", "PositionX"),all=T),datlist) 

例如文件1有,

id PositionX val1 
1 5 4.2 
2 8 4.3 

和文件2具有

id PositionX val2 
    1 5 6.3 
    2 8 9.3 

和文件3具有

id PositionX val3 
     0 5 6.2 
     2 8 9.3 

我想有

 id PositionX val1 val2 val3 
     0 5 NA NA 6.2 
     1 5 4.2 6.3 NA 
    ... 

有沒有辦法快速做到這一點?

+0

你從'dplyr'包中檢查過'full_join'嗎? – Aramis7d

+0

這有點不清楚。你想要結合多個CSV文件(數據幀),它們有id,positionX和其他數據。還有其他什麼數據如果兩個以上的csv文件具有相同的id,positionX變量?輸出數據中會有多少個變量?你只是想從長格式轉換爲寬格式嗎?顯示一些示例輸入和輸出。 – Spacedman

+0

@Spacedman我希望這很清楚。 – Jamil

回答

1

不確定SQL是否能夠處理該大文件,但如果使用SQL服務器,則可以使用if-then-when命令進行連接。

1

使用data.table包做得更快(可用)

library(data.table) 
df1=data.table(df1) 
df2=data.table(df2) 
df3=data.table(df3) 

setkey(df1, id, PositionX) 
setkey(df2, id, PositionX) 
setkey(df2, id, PositionX) 

j1=df1[df2, alpha := i.alpha] 
j2=df3[j1, alpha := i.alpha] 

在基礎R這絕對作品

> df1 
    id PositionX val1 
1 1   5 4.2 
2 2   8 4.3 
> df2 
    id PositionX val2 
1 1   5 6.3 
2 2   8 9.3 
> df3 
    id PositionX val3 
1 0   5 6.2 
2 2   8 9.3 
> merge(df1,df2,by=c("id","PositionX")) 
    id PositionX val1 val2 
1 1   5 4.2 6.3 
2 2   8 4.3 9.3 
> j1=merge(df1,df2,by=c("id","PositionX")) 
> j1 
    id PositionX val1 val2 
1 1   5 4.2 6.3 
2 2   8 4.3 9.3 
> merge(j1,df3,by=c("id","PositionX")) 
    id PositionX val1 val2 val3 
1 2   8 4.3 9.3 9.3 
> merge(j1,df3,by=c("id","PositionX"),all=T) 
    id PositionX val1 val2 val3 
1 0   5 NA NA 6.2 
2 1   5 4.2 6.3 NA 
3 2   8 4.3 9.3 9.3 

dplyr會工作得更快上data.table格式 http://stat545.com/bit001_dplyr-cheatsheet.html#full_joinsuperheroes-publishers

+1

請閱讀更新後的問題,不要跳到不明確的問題上。 – Spacedman

+0

Aye Aye船長! –

1

full_join from dlpyr程序包比merge要快一些。再現的例子如下:

> set.seed(123) 
> library(dplyr) 
> d = data.frame(id=1:100,Pos=1:100,val1=runif(100)) 
> f1 = d[sample(100,80),] 
> f2 = d[sample(100,80),] 
> f3 = d[sample(100,80),] 
> names(f2)[3]="val2" 
> names(f3)[3]="val3" 
> head(f1) 
    id Pos  val1 
60 60 60 0.3744628 
33 33 33 0.6907053 
48 48 48 0.4659625 
93 93 93 0.3435165 
47 47 47 0.2330341 
85 85 85 0.1028646 
> head(f2) 
    id Pos  val2 
84 84 84 0.7881958 
31 31 31 0.9630242 
70 70 70 0.4398317 
26 26 26 0.7085305 
58 58 58 0.7533079 

同樣地,對於f3

要使用dplyr做合併,它的:

> jd = Reduce(full_join, list(f1,f2,f3)) 
Joining, by = c("id", "Pos") 
Joining, by = c("id", "Pos") 

,並提供:

> head(jd %>% arrange(id)) 
    id Pos  val1  val2  val3 
1 1 1 0.2875775  NA 0.2875775 
2 2 2  NA  NA 0.7883051 
3 3 3  NA 0.4089769 0.4089769 
4 4 4  NA 0.8830174 0.8830174 
5 5 5 0.9404673 0.9404673 0.9404673 
6 6 6 0.0455565  NA 0.0455565 

這是一樣的:

> head(Reduce(function(df1,df2) merge(df1,df2,by=c("id", "Pos"),all=T),list(f1,f2,f3))) 
    id Pos  val1  val2  val3 
1 1 1 0.2875775  NA 0.2875775 
2 2 2  NA  NA 0.7883051 
3 3 3  NA 0.4089769 0.4089769 
4 4 4  NA 0.8830174 0.8830174 
5 5 5 0.9404673 0.9404673 0.9404673 
6 6 6 0.0455565  NA 0.0455565 

除了不id排序(因此arrange)。

爲基準,首先我們需要一個full_join包裝函數指定的列,這樣,當我們的基準它,它不花所有的時間尖叫消息:

> fj = function(a,b){full_join(a,b,by=c("id","Pos"))} 

現在,我們可以運行後的基準使用library(microbenchmark)

> microbenchmark(Reduce(fj,list(f1,f2,f3)),Reduce(function(df1,df2) merge(df1,df2,by=c("id", "Pos"),all=T),list(f1,f2,f3))) 
Unit: microseconds 
                          expr 
                    Reduce(fj, list(f1, f2, f3)) 
Reduce(function(df1, df2) merge(df1, df2, by = c("id", "Pos"),  all = T), list(f1, f2, f3)) 
     min  lq  mean median  uq  max neval 
    860.491 901.746 1108.901 936.0205 1016.623 6951.609 100 
3133.837 3245.754 4092.630 3291.7825 3616.122 15828.191 100 

你的實際加速(或減速)可能取決於您如何匹配是稀疏,有多少行,列,數據幀等。