【问题标题】:R function loops twice?R函数循环两次?
【发布时间】:2019-06-02 12:03:28
【问题描述】:

我编写了一个循环,它输入几个文本文件,对每个文件执行一些功能并将它们组合起来。我在下面复制了它并注释了每一行。但是,i 中的第一个文件被读入(并添加到我的决赛桌)两次! 另外,期待简化这个循环。

source_files<-list.files(pattern="_output.txt") # This line finds all file ending with .txt
上面的

source_files 列出了要在下面的循环中输入的适当文件。

for (i in source_files){
    if (!exists("final_table")){
        df_import<-read.table(i, header=FALSE, sep="\t") # reads in each file
        names<-unlist(strsplit(i,"_")) # reformats input file name and parses to 'names'
        df_import$Sample<-names[1] # replaces col[1] header with first part of file name
        df_import$DB<-names[2] # replaces col[1] header with first part of file name
        final_table<-df_import # creates the final table data frame
        rm(df_import) # remove excess df
        }
    if (exists("final_table")){
        df_import<-read.table(i, header=FALSE, sep="\t") # reads in each file
        names<-unlist(strsplit(i,"_")) # reformats input file name and parses to 'names'
        df_import$Sample<-names[1] # replaces col[1] header with first part of file name
        df_import$DB<-names[2] # replaces col[1] header with first part of file name
        final_table <-rbind(final_table, df_import) # Adds to existing final table
        rm(df_import)   
    }
}

这个循环运行良好,除了 final_table 有重复 - 有什么建议吗?

【问题讨论】:

  • 您也可以在for 循环之外初始化final_table,完全不需要if/else

标签: r for-loop nested-loops


【解决方案1】:

好吧,您测试该表是否存在于第一个if 中,如果不存在,则创建它并在其中添加一行。因此,当您到达第二个if 时,该表确实存在,但它再次添加了该行。不要使用两个if 语句,而是使用一个if/else。也可能只是将final_table &lt;-... 行移到if 中,然后将其他行移出,这样您就不会有太多重复的代码。

也许

for (i in source_files){
    df_import<-read.table(i, header=FALSE, sep="\t") # reads in each file
    names<-unlist(strsplit(i,"_")) # reformats input file name and parses to 'names'
    df_import$Sample<-names[1] # replaces col[1] header with first part of file name
    df_import$DB<-names[2] # replaces col[1] header with first part of file name
    if (!exists("final_table")){
        final_table<-df_import # creates the final table data frame
    } else {
        final_table <-rbind(final_table, df_import) # Adds to existing final table
    }
    rm(df_import) # remove excess df
}

那些有更好的方法来做到这一点,而不是每次都循环和 rbinding。看到这个答案:What's wrong with my function to load multiple .csv files into single dataframe in R using rbind?

【讨论】:

  • 这样更精简并解决了问题。谢谢!
【解决方案2】:

我会采取稍微不同的方法。看来您的if() 块中的唯一区别是您对final_table 所做的事情。我可能会按照这些思路做一些事情:

#This mimics your list.files() call
list_of_files <- list(mtcars, mtcars, mtcars)

#put the guts of your code inside a function
process_file <- function(file) {
  #your stuff goes here - I'm just going to add a random variable named foo      
  file$foo <- rnorm(nrow(file))
  return(file)
}
#use lapply to iterate over your list of files and do.call to bind them together
output <- do.call("rbind", lapply(list_of_files, process_file))

reprex package (v0.2.1) 于 2019-01-07 创建

【讨论】:

  • 这也是 lapply() 的一个很好的用途,可以用于需要处理多个数据帧的其他类型的 for 循环等。谢谢!
猜你喜欢
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 2013-04-10
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
  • 2023-03-15
  • 1970-01-01
相关资源
最近更新 更多