循环csv文件

时间:2014-03-07 14:54:40

标签: r loops 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绑定它们。我想以更优雅的方式做到这一点,这就是我来这里的原因!

2 个答案:

答案 0 :(得分: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)

在看到每个文件中感兴趣的各种行/列的复杂性后,我认为你可以做这样的事情。看起来有点笨拙,但可以完成工作。我假设您基于名为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

这是你在想什么或者我误解了吗?

答案 1 :(得分:0)

不是ldplyr()在JPC的答案中以与do.call()相同的方式运行....我恰好使用plyr更多,如果你正在寻找以矢量化方式操作r数据结构然后很多有用的东西在那里。

library(plyr)

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

选择d1和d2的cols

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

final.df&lt; - cbind(d1,d2)