ускорение вложенной инструкции ifelse — R

#r #if-statement #nested

#r #if-оператор #вложенный

Вопрос:

Пример на этом этапе моего кода:

     time_elapsed                     network_name             daypart       day
 1:         4705                          Laff TV 2016-09-09 03:11:35    Friday
 2:         1800                              CNN 2016-09-10 08:00:00  Saturday
 3:           23                             INSP 2016-09-02 18:00:00    Friday
 4:          148                              NBC 2016-09-02 16:01:26    Friday
 5:          957                  History Channel 2016-09-07 14:44:03 Wednesday
 6:         1138         Nickelodeon/Nick-at-Nite 2016-09-09 16:00:00    Friday
 7:          120                       Starz Edge 2016-09-07 15:28:59 Wednesday
 8:          268            Starz Encore Westerns 2016-09-07 17:13:05 Wednesday
 9:            6                              CBS 2016-09-10 04:00:00  Saturday
10:           69                      Independent 2016-09-07 12:48:11 Wednesday
11:         4151                              NBC 2016-09-09 04:32:37    Friday
12:          570 PBS: Public Broadcasting Service 2016-09-07 16:17:58 Wednesday
13:         1421                            NBCSN 2016-09-03 15:22:23  Saturday
14:          466          Estrella TV (Broadcast) 2016-09-04 19:00:00    Sunday
  

(обычно более 200 миллионов строк)

Я написал следующую вложенную инструкцию ifelse пару месяцев назад, когда я запускал весь свой скрипт всего на пару миллионов строк, но теперь, когда я запускаю его в большем масштабе, мне бы очень хотелось найти способ сделать это немного быстрее.

 targets_random$daypart <- ifelse((wday(targets_random$daypart) == 1 | 
                wday(targets_random$daypart) == 7), "W: Weekend",
                        ifelse(hour(targets_random$daypart) <= 2, "LP: Late Prime",
                        ifelse((hour(targets_random$daypart) >= 3 amp; 
                hour(targets_random$daypart) <= 5), "O: Overnight",
                        ifelse((hour(targets_random$daypart) >= 6 amp; 
                hour(targets_random$daypart) <= 9), "EM: Early Morning",
                        ifelse((hour(targets_random$daypart) >= 10 amp; 
                hour(targets_random$daypart) <= 16), "D: Day",
                        ifelse((hour(targets_random$daypart) >= 17 amp; 
                hour(targets_random$daypart) <= 20), "F: Fringe",
                        ifelse(hour(targets_random$daypart) >= 21, "P: Prime", NA)))))))
  

Я попытался использовать решение data.table, но оно было лишь немного быстрее и преобразовало мой data.table в список. Хоть убей, я не мог понять, почему. Это добавило достаточно времени для отмены, но экономия не стоила.

Любые предложения будут высоко оценены. То, что у меня есть, работает, и если я должен придерживаться этого, все будет хорошо. В настоящее время для выполнения полного кода требуется около 3,5 часов. Самая большая часть — это SQL-запрос и создание файла результатов, но было бы неплохо, если бы я мог сэкономить как можно больше времени!

(В качестве примечания — раньше прошло почти 8 часов, прежде чем я заменил тонны деталей синтаксисом data.table. Теперь я официальный фанат!)

Комментарии:

1. Возможно, вы сможете использовать parLapply для одновременного запуска нескольких строк

2. См ?cut . Кажется, что вы могли бы использовать что-то вроде cut(targets_random$daypart$hour, c(-Inf, 3, 6, 10, 17, 21, Inf), include.lowest = TRUE, right = FALSE) , но, изменив аргумент «labels» на c("LP: Late Prime", "O: Overnight", etc...) и, после чего заменив на "W: Weekend" wherever (targets_random$daypart$wday 1) %in% c(1, 7)

Ответ №1:

Рассмотрите возможность создания отдельного статического фрейма данных daytimes из всех возможных комбинаций и их результата. На практике SQL это будет считаться таблицей поиска. Затем обычно выполняется слияние с полной таблицей данных.

 # DF (N=168) 7 X 24
daytimes <- expand.grid(wday=c(1:7),
                        hour=c(1:24))    
daytimes$result <- 
  ifelse((daytimes$wday == 1|daytimes$wday == 7), "W: Weekend",
       ifelse(daytimes$hour <= 2, "LP: Late Prime",
             ifelse((daytimes$hour >= 3 amp; daytimes$hour <= 5), "O: Overnight",
                    ifelse((daytimes$hour >= 6 amp; daytimes$hour <= 9), "EM: Early Morning",
                           ifelse((daytimes$hour >= 10 amp; daytimes$hour <= 16), "D: Day",
                                  ifelse((daytimes$hour >= 17 amp; daytimes$hour <= 20), "F: Fringe",
                                         ifelse(daytimes$hour >= 21, "P: Prime", NA)))))))
# CREATE MERGE FIELDS
targets_random$wday <- wday(targets_random$daypart)
targets_random$hour <- hour(targets_random$daypart)

# MERGE WITH NEW COLUMN: result
targets_random <- merge(targets_random, daytimes, by=c("wday", "hour"))         
  

Комментарии:

1. Оооо, я собираюсь попробовать это!