Чтение / запись в L oop с предварительным выделением памяти в R - PullRequest
1 голос
/ 29 января 2020

У меня есть рабочий l oop для чтения текстовых файлов (неизвестные имена) из разных папок (известное местоположение), обновления столбцов этих текстовых файлов и повторного сохранения с тем же именем в той же папке

folders <- c(1,2,3)

for(i in seq_along(folders)){
        dt <- df[(df$id ==folders[i]),]
        dt$id <- NULL
        loc <- paste0("data/", folders[i])
        setwd(loc)
        file.names <- list.files(pattern = "*.txt$", all.files = FALSE,
                                 full.names = FALSE, recursive = FALSE,
                                 ignore.case = FALSE)


    for(j in seq_along(file.names)){
      text <- read.csv(file.names[j], header = F, stringsAsFactors = F)

      text2 <- merge(text, dt, by.x = "matched", by.y = "matched", all.x = T)
      write.table(text2, file.names[j], sep = ",", na="",
                  row.names = FALSE, quote = TRUE, col.names = F)
      rm(text,text2)
      print(j)
    }
}

Есть две проблемы, с которыми я сталкиваюсь: первая очень медленная, вторая использует слишком много памяти / памяти. Пытался сделать сам, но не очень разбираюсь в R. Можно увеличить скорость, создав некоторые функции и «если просто инициализировать вектор (с NA, нулями или любым другим значением) с общей длиной, а затем запустить l oop, мы можем резко увеличить скорость нашего алгоритма ". Я мог бы sh Я мог бы сделать что-то подобное сам.

1 Ответ

0 голосов
/ 29 января 2020

Скорость адресации

Я бы порекомендовал некоторые операторы печати во всех ваших циклах и посмотреть, где расходуется время.

Адресация памяти (и скорость)

Вы используете базовые функции R. Попробуйте использовать dplyr::left_join() вместо merge (dplyr имеет тенденцию работать c++ под колпаком, и, следовательно, в ~ 100 раз быстрее, чем эквивалентные функции в базе R). Вы также можете попробовать некоторые data.table функции

rm() удалить объекты, но на самом деле не освобождает память. Вызов gc() после rm() освободит большую часть памяти, занятой удаленными объектами. Поэтому попробуйте поставить gc() после звонка rm().

Относительно предварительного распределения вектора

Предварительное распределение вектора помогает, потому что это уменьшает необходимость для R делать копии векторов при их объединении. Это не является проблемой здесь (поскольку ваш код не объединяет векторы).

...