【问题标题】:Looping over csv files循环遍历 csv 文件
【发布时间】:2014-04-10 19:06:49
【问题描述】:

所以,我创建了一个 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 绑定它们。我想以更优雅的方式做到这一点,所以这就是我来这里的原因!

【问题讨论】:

    标签: r loops csv


    【解决方案1】:

    我建议查看 do.call ,您可以 rbind 您的第一个表列表,然后 rbind 您的第二个表列表,然后按照您的说明进行 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
    

    这是你的想法还是我误解了?

    【讨论】:

    • 问题是我在每个 csv 文件中有不同数量的行/列。一些名称是重复的,并以不同的顺序排列。我不知道 do.call 是否能够处理此类问题。这就是为什么我决定用循环来做这件事。我制作了一个我感兴趣的名称向量,并尝试从每个 csv 文件中选择有趣的值并将它们放在一个表中。如果有人会帮助我,我可以写一个新的“线程”并解释一切。
    • 啊,我明白了。我没有注意到您的问题中的细微差别。所以说你有一个 csv 文件 1 有 10 行和 2 列感兴趣,另一个文件 2 有 3 行和 3 列感兴趣。你将如何将这些结合起来?有没有打算合并的钥匙?
    • 很抱歉回复晚了,但我刚搬到新公寓,家里没有互联网连接,只是在工作。大约有 20 个 csv 文件,它们都有 15-20 列和 3000 行。有些行的名称是相同的,有些是不同的。我创建了一个包含所有行名的向量,现在我想用所有 csv 文件中 4 列的数据填充表格。所以我将以一列基因名称结束,然后像 80 列数据(每个 csv 文件中的 4 列)。这就是为什么我想创建一个循环来收集所有数据。
    • 如果我没看错的话,听起来你的基因名称就是你想要合并的,对吗?如果您已经知道这些,那么为什么不创建一个 data.frame 并将它们作为一列,然后按照上述方法将所有内容合并到该列上呢?
    【解决方案2】:

    不是 ldplyr() 函数的方式与 JPC 的答案中的 do.call() 相同。...在那里。

    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

    【讨论】:

      猜你喜欢
      • 2019-07-21
      • 2019-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2018-02-07
      • 2017-10-02
      相关资源
      最近更新 更多