Функция R повторяется дважды? - PullRequest
0 голосов
/ 07 января 2019

Я написал цикл, который вводит несколько текстовых файлов, выполняет несколько функций для каждого и объединяет их. Я скопировал это ниже и аннотировал каждую строку. Однако, первый файл в 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 имеет дублирование - есть предложения?

Ответы [ 2 ]

0 голосов
/ 07 января 2019

Я бы выбрал немного другой подход. Похоже, единственная разница в вашем блоке 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))

Создано в 2019-01-07 пакетом Представить (v0.2.1)

0 голосов
/ 07 января 2019

Итак, вы проверяете, существует ли таблица в первом if, а если нет, то создает ее и добавляет к ней строку. Поэтому, когда вы переходите ко второму if, таблица существует, но она снова добавляет строку. Вместо использования двух операторов 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
}

Те, что есть лучшие способы сделать это, вместо того, чтобы каждый раз зацикливаться и связываться. Смотрите этот ответ: Что не так с моей функцией загрузки нескольких файлов .csv в один кадр данных в R с использованием rbind?

...