Есть ли более простой способ, чем использовать цикл for для генерации CSV-файлов, касающихся 4000 городов с использованием R? - PullRequest
0 голосов
/ 19 января 2019

Я пытаюсь создать отдельные файлы CSV для около 4000 городов, используя R. Я написал небольшой цикл для этого.

Все данные о городах хранятся в одном отдельном фрейме данных под названием towns_files. В цикле for я разделяю эти консолидированные фреймы данных на небольшой временный фрейм данных для каждого города и записываю этот временный фрейм данных в файл csv.

cities.list <-  unique(cities_files$city_name)

for( cities.list  in cities_files$city_name )   {

tmp <- subset(cities_files,city_name == cities.list) 
cit.name <- unique(tmp$city_name)
fn = paste(paste(cit.name) ,".csv", sep = '')     
write.csv(tmp,fn ,row.names = FALSE)
}

Однако для создания этих 4000 файлов цикл for занимает около 3 часов. Могу ли я использовать что-то кроме цикла for для получения желаемых результатов? Или есть лучший способ оптимизировать этот код? Я хочу сократить время, необходимое для создания этих файлов.

1 Ответ

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

Вы просматриваете каждое наблюдение.Возможно, вы захотите рассмотреть подход data.table.

Обновление
Как указал @MichaelChirico, следует использовать метод data.table::split.

library(data.table)

cities_files <- data.frame(bar = c(1:20000), 
                        city_name  = rep(paste0("city ", 1:200), 100), 
                        foo = c(1:20000))


microbenchmark::microbenchmark(
    khaynes = {
        # library(data.table)
        # Set the data.frame as a data.table
        cities_files_dt <- data.table(cities_files)
        lapply(unique(cities_files_dt[, city_name]), function(city) 
            fwrite(x = subset(cities_files_dt, city_name  == city), 
            file = paste0(city, ".csv")))

    },
    MichaelChirico = {
        cities_files_dt <- data.table(cities_files)
        list_dt <- split(cities_files_dt, cities_files_dt$city_name)
        for(i in 1:length(list_dt)) {
            fwrite(list_dt[[i]], paste0(names(list_dt[i]), ".csv"))
        }
    },
    times = 5
)
# Unit: milliseconds
#       expr      min       lq     mean   median       uq      max neval
#    khaynes 661.0689 680.6768 698.2449 683.1407 719.8056 746.5323     5
#    MichaelChirico 452.0800 456.5777 499.2832 458.0174 517.4398 612.3011     5

Использование пакета data.table должно значительно ускорить время обработки:

library(data.table)

# Create a dummy data.frame
cities_files <- data.frame(bar = c(1, 1, 2, 3, 3), 
                        city_name  = c("city a", "city a", "city b", "city c", "city c"), 
                        foo = c(20, 14, 40, 50, 60))

# Set the data.frame as a data.table
setDT(cities_files)

lapply(unique(cities_files[, city_name ]), function(city) 
    fwrite(x = subset(cities_files, city_name  == city), 
    file = paste0(city, ".csv")))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...