2014-03-07 89 views
2

所以,我創建了一個列表的CSV文件:循環執行的CSV文件

tbl = list.files(pattern="*.csv") 

然後,我把他們分開成兩個不同的列表:

tbl1 <- tbl[c(1,3:7,10:12,14:18,20)] 
tbl2 <- tbl[c(2,19,8:9,13)] 

然後加載它們:

list_of_data1 = lapply(tbl1, read.csv) 
list_of_data2 = lapply(tbl2, read.csv) 

現在我想創建一個主文件。我只想從每個csv文件中選擇一些數據並將其存儲在一個表中。要做到這一點,我創建這樣的循環:

gdata1 = lapply(list_of_data1,function(x) x[3:nrow(x),10:13]) 

for(i in 1:length(list_of_data1)){ 
rownames(gdata1[[i]]) = list_of_data1[[i]][3:nrow(list_of_data1[[i]]),1] 
} 
tmp = lapply(gdata1,function(x) matrix(as.numeric(x),ncol=4)) 


final.table1=c() 
for(i in 1:length(gnames)){ 
     print(i) 
     tmp=gnames[i] 
     f1 = function(x) {x[tmp,]} 
     tmp2 = lapply(gdata1,f1) 
     tmp3 = c() 
     for(j in 1:length(tmp2)){ 
      tmp3=rbind(tmp3,tmp2[[j]]) 
     } 
     tmp4 = as.vector(t(tmp3)) 
     final.table1 = rbind(final.table1,tmp4) 
} 

rownames(final.table1) = gnames 

我創建的數據的兩份不同名單,因爲在第一個list_of_data1有四個有趣列,我(10:13)和另一個list_of_data2只有3列(10:12)。我想把所有的數據放在一張表中。有沒有辦法在一個循環中完成它?

我有一個想法如何解決這個問題。我可以爲list_of_data2創建一個新循環,然後使用cbind將它們兩者綁定。我想以更優雅的方式來做,所以我來到這裏!

回答

1

我會建議您查看do.call,您可以將您的第一張表格清空,然後按照您的說法清除第二個表格列表,然後按照您的說法執行cbind。下面一個簡單的使用do.call

#creating a list of tables that we are interested in appending 
#together in one master dataframe 
ts<-lapply(c(1,2,3),function(x) data.frame(c1=rep(c("a","b"),2),c2=(1:4)*x,c3=rnorm(4))) 

#you could of course subset ts to the set of columns 
#you find of interest ts[,colsOfInterest] 
master<-do.call(rbind,ts) 

的看到你的各種行的併發症後/在每個文件的興趣列,我想你可以做這樣的事情。似乎有點ha but,但可以完成工作。我假設你合併基於一個名爲列ID文件,你當然可以這樣概括,以多列等

#creating a series of data frames for which we only want a subset of row/cols 
> df1<-data.frame(id=1:10,val1=rnorm(10),val2=rnorm(10)) 
> df2<-data.frame(id=5:10,val3=rnorm(6)) 
> df3<-data.frame(id=1:3,val4=rnorm(3), val5=rnorm(3), val6=rnorm(3)) 
#specifying which rows/cols we are interested in 
#i assume you have some way of doing this programmatically or you defined elsewhere 
> colsofinterest<-list(df1=c("id","val1"),df2=c("id","val3"),df3=c("id","val5","val6")) 
> rowsofinterest<-list(df1=1:5,df2=5:8,df3=2:3) 
    #create a list of data frames where each has only the row/cols combination we want 
> ts<-lapply(c("df1","df2","df3"), 
     function(x) get(x)[rowsofinterest[[x]],colsofinterest[[x]]]) 
> ts 
[[1]] 
    id  val1 
1 1 0.24083489 
2 2 -0.50140019 
3 3 -0.24509033 
4 4 1.41865350 
5 5 -0.08123618 

[[2]] 
    id  val3 
5  9 -0.1862852 
6 10 0.5117775 
NA NA   NA 
NA.1 NA   NA 

[[3]] 
    id  val5  val6 
2 2 0.2056010 -0.6788145 
3 3 0.2057397 0.8416528 

#now merge these based on a key column "id", and we want to keep all. 
> final<-Reduce(function(x,y) merge(x,y,by="id",all=T), ts) 
> head(final) 
    id  val1  val3  val5  val6 
1 1 0.24083489   NA  NA   NA 
2 2 -0.50140019   NA 0.2056010 -0.6788145 
3 3 -0.24509033   NA 0.2057397 0.8416528 
4 4 1.41865350   NA  NA   NA 
5 5 -0.08123618   NA  NA   NA 
6 9   NA -0.1862852  NA   NA 

這是你在想什麼還是我誤解?

+0

的問題是,我在每個CSV不同數目的行/列的文件。一些名字重複並且以不同的順序變化。我不知道do.call是否能夠處理這些問題。這就是爲什麼我決定用循環做到這一點。我製作了一個我感興趣的名稱矢量,並嘗試從每個csv文件中選擇有趣的值,並將它們放在一個表中。如果有人有機會幫助我,我可以寫一個新的「線索」並解釋一切。 –

+0

啊,我明白了。我沒有注意到你的問題中的細微差別。因此,假設您有一個包含10行2列的csv文件1,另一個文件2包含3行3列感興趣的文件。你將如何去結合這些?您計劃合併的關鍵是否? – JPC

+0

對不起,遲到了,但我剛搬到新的公寓,我在家裏沒有互聯網連接,只是在工作。有20個csv文件,他們都有15-20列和3000行。一些行的名稱是相同的,其中一些是不同的。我創建了一個包含所有行名稱的向量,現在我想用來自所有csv文件中的4列的數據填充表格。所以我將以基因名稱的一列結束,然後像80列數據(每個csv文件4列)。這就是爲什麼我想要創建一個可以收集所有數據的循環。 –

0

不是ldplyr()的功能與JPC的答案中的do.call()相同....我只是碰巧使用plyr更多,如果您正在尋找以矢量化方式操作r數據結構,那麼很多有用的那裏的東西。

library(plyr) 

d1 <- ldplyr(list_of_data1, rbind) 
d2 <- ldplyr(list_of_data2, rbind) 

的d1和d2

d1 <- d1[,c(10:13)] 
d2 <- d2[,c(10:12)] 

final.df <選擇欄位 - cbind(D1,D2)