For-loop над списком txt.files с условиями if в R - PullRequest
0 голосов
/ 31 октября 2018

Я борюсь с созданием цикла for для всех файлов txt.files в конкретном репозитории. Цель состоит в том, чтобы объединить все отдельно сохраненные файлы txt.files в кадре данных и добавить переменную ID, которая всегда может быть найдена в именах файлов txt (например, ID = 10 для файла "10_1. Запись 01.10.2015 131514_CsvData. txt ")

txt_files <- list.files("Data/study", pattern = ".txt")  

txt_files [1] «1_1. Запись 18.09.2015 091037_CsvData.txt» «10_1. Запись 01.10.2015 131514_CsvData.txt»
[3] "100_1. Запись 02.10.2015 091630_CsvData.txt" "104_1. Запись 22.09.2015 142604_CsvData.txt"
[5] "107_1. Запись 18.09.2015 104300_CsvData.txt" "110_1. Запись 29.09.2015 081558_CsvData.txt"
[7] "112_1. Запись 21.09.2015 082908_CsvData.txt" "114_1. Запись 29.09.2015 101159_CsvData.txt"
[9] "115_1. Запись 23.09.2015 141204_CsvData.txt" "116_1. Запись 30.09.2015 110624_CsvData.txt"
[11] "117_1. Запись 01.10.2015 141227_CsvData.txt" "120_1. Запись 17.09.2015 153516_CsvData.txt"

Читать и объединять txt.files

    for ( file in txt_files){
    #  if the merged dataframe "final_df" doesn't already exist, create it
    if (!exists("final_df")){
    final_df<- read.table(paste("Data/study/",file, sep=""), header=TRUE, fill=TRUE)
    temp_ID <- substring(file, 0,str_locate_all(pattern ='_1.',file)[[1]][1]-1)
    final_df$ID <- temp_ID
    final_df <- as.data.frame(final_df)
  }
  #  if the merged dataframe does already exist, append to it
  else {
    temp_dataset <- read.table(paste("Data/study/",file, sep=""), header=TRUE, fill=TRUE)
    #   extract ID column from filename
    temp_ID <- substring(file, 0,str_locate_all(pattern ='_1.',file)[[1]][1]-1)
    temp_dataset$ID <- temp_ID
    final_df<-rbind(final_df, temp_dataset)
  }
  return(as.data.frame(final_df))
}

1 Ответ

0 голосов
/ 31 октября 2018

Избегайте использования rbind в цикле, что приводит к чрезмерному копированию в памяти. Попробуйте создать список фреймов данных и связать их один раз с do.call вне любого цикла. Для этого подхода lapply является полезной итеративной альтернативой, чем for, для создания такого списка фреймов данных, поскольку вы избегаете учета инициализации пустого списка и итеративного обновления элементов.

Также рассмотрим paste0 без аргумента разделителя и gsub, чтобы удалить любые символы от подчеркивания до конца строки для извлечения идентификатора.

setwd("Data/study")
txt_files <- list.files(pattern = ".txt")  

df_list <- lapply(txt_files, function(file)  
                  transform(read.table(file, header=TRUE, fill=TRUE),
                            temp_ID = gsub("_.*", "", file))   
           )

final_df <- do.call(rbind, df_list)
...