在df列表上循环一个函数并将结果保存在r中

时间:2016-02-25 17:38:13

标签: r list paste lapply

我有不同的数据框,我想做的是:

  1. 将重复次数的函数应用于每个数据帧
  2. 在新数据框架上保存每次重复的结果,保留原始数据框架的名称并添加其他内容以区分它
  3. 这是我到现在为止所尝试的内容

     # read all files to list
     dataframes <- dir( pattern = ".txt") 
     list_dataframes <- llply(dataframes, read.csv, header = T, sep =" ", dec=".", na.string = "nd")  
     n <- length(dataframes)
    
     # apply myfunction 10 times
    for (j in 1:10){
    modified_list <- llply(list_dataframes, myfunction) 
    }
    if (j <10){
    num.char <- paste("n0", j, sep="")
    } else num.char <- paste("n", j, sep="")
    
    # save back data frames
    for (i in 1:n)
    write.table(file = paste( "newfile/_modified",num.char, ".csv", sep = ""), 
    modified_list[i], row.names = F)
    

    我想要的结果是修改后的数据帧(在这种情况下,列表的每个df重复10次)将具有:

    • 原始df的名称
    • 新名称
    • 和迭代次数

      originaldfname_newname_n0

    • 之类的东西

    我找不到我错过的地方。任何帮助将深表赞赏

1 个答案:

答案 0 :(得分:1)

我认为有两个主要问题:

  • }(上面第9行)应该在您的第二个for循环之后;

  • 您的上一行应该引用modified_list[[i]],而不是使用单一的[表示法。

所以你的代码应该可以工作(未经测试,稍微修改了样式):

library(plyr)

# read all files to list
dataframes <- dir(pattern = ".txt") 
list_dataframes <- llply(dataframes, read.csv,
                         header = T, sep = " ", dec=".", na.string = "nd")  
n <- length(dataframes)

# apply myfunction 10 times
for (j in 1:10) {
  modified_list <- llply(list_dataframes, myfunction) 
  # save back data frames
  for (i in 1:n)
    write.table(file = sprintf("newfile/%s_newname_%02d.csv", dataframes[i], j), 
                modified_list[[i]], row.names = FALSE)
}

如果这是代码高尔夫,最后一部分可以减少一点:

for (j in 1:10) {
  mapply(function(df, nm) write.csv(file = sprintf('newfile/%s_newname_%02d.csv', nm, j),
                                    df, row.names = FALSE),
         llply(list_dataframes, myfunction), dataframes)
}

(这并不一定能让它更清晰,但它确实会减少一点。如果你在某些时候更喜欢不使用for循环,请使用它,尽管在这种情况下的性能将是几乎相同。)

注意:

  • 请包含必需的库,例如library(plyr)
  • 虽然lapply可以正常使用,但我仍然使用llply来匹配您的示例。