R函数循环两次?
R function loops twice?
我写了一个循环,它输入几个文本文件,对每个文件执行一些函数并将它们组合起来。我已将其复制到下方并为每一行添加了注释。但是,i 中的第一个文件被读入(并添加到我的最终 table 中)两次!
此外,期待简化此循环。
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 有重复 - 有什么建议吗?
那么,您测试 table 是否存在于第一个 if
中,如果不存在,则创建它并向其添加一行。因此,当您到达第二个 if
时,table 确实存在,但它会再次添加该行。与其使用两个 if
语句,不如使用一个 if/else
。也可能只是将 final_table <-...
行移到 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?
我会采取稍微不同的方法。您的 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 创建
我写了一个循环,它输入几个文本文件,对每个文件执行一些函数并将它们组合起来。我已将其复制到下方并为每一行添加了注释。但是,i 中的第一个文件被读入(并添加到我的最终 table 中)两次! 此外,期待简化此循环。
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 有重复 - 有什么建议吗?
那么,您测试 table 是否存在于第一个 if
中,如果不存在,则创建它并向其添加一行。因此,当您到达第二个 if
时,table 确实存在,但它会再次添加该行。与其使用两个 if
语句,不如使用一个 if/else
。也可能只是将 final_table <-...
行移到 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?
我会采取稍微不同的方法。您的 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 创建