Перебор списка параметров с использованием тидикванта R - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть набор данных, который я хочу обработать, используя tq_mutate, и использовать разные значения параметров.

В настоящее время я использую цикл for, чтобы просмотреть все значения параметров, но я уверен, что это не самый эффективный или самый быстрый способ решения этой задачи (особенно, когда я собираюсь посмотреть в целомномера значений параметров).Как улучшить или удалить цикл for?Я подозреваю, что это означает использование purrr :: map или других средств (многопоточность / многоядерность и т. Д.), Но я не смог найти полезных примеров в Интернете.

Ниже приведен пример кода.Пожалуйста, игнорируйте простоту набора данных и выводов функции масштабирования, это только для иллюстрации.Что я хочу сделать, так это перебирать множество различных значений V0.

library(dplyr)
library(tidyverse)
library(broom)
library(tidyquant)

my_bogus_function <- function(df, V0=1925) { 
  # WILL HAVE SOMETHING MORE SOPHISTICATED IN HERE BUT KEEPING IT SIMPLE
  # FOR THE PURPOSES OF THE QUESTION
  c(V0, V0*2)
}

window_size <- 7 * 24
cnames = c("foo", "bar")
df <- c("FB") %>%
    tq_get(get = "stock.prices", from = "2016-01-01", to = "2017-01-01") %>% 
    dplyr::select("date", "open")

# CAN THIS LOOP BE DONE IN A MORE EFFICIENT MANNER? 
for (i in (1825:1830)){
  df <- df %>% 
        tq_mutate(mutate_fun = rollapply,
                  width      = window_size,
                  by.column  = FALSE,
                  FUN        = my_bogus_function,
                  col_rename = gsub("$", sprintf(".%d", i), cnames), 
                  V0 = i
    )
}
# END OF THE FOR LOOP I WANT FASTER

1 Ответ

0 голосов
/ 27 ноября 2018

Учитывая, что R использует одно ядро, я обнаружил улучшение, используя параллельные пакеты, doSNOW и foreach, которые позволяют использовать несколько ядер (обратите внимание, что я на Windows-машине, поэтому некоторые другие пакеты недоступны).

Я уверен, что есть другие ответы на многопоточный / параллельный / векторизованный код.

Вот код для всех, кто интересуется.

library(dplyr)
library(tidyverse)
library(tidyquant)
library(parallel)
library(doSNOW)  
library(foreach)

window_size <- 7 * 24
cnames = c("foo", "bar")
df <- c("FB") %>%
  tq_get(get = "stock.prices", from = "2016-01-01", to = "2017-01-01") %>% 
  dplyr::select("date", "open")

my_bogus_function <- function(df, V0=1925) { 
  # WILL HAVE SOMETHING MORE SOPHISTICATED IN HERE BUT KEEPING IT SIMPLE
  # FOR THE PURPOSES OF THE QUESTION
  c(V0, V0*2)
}

# CAN THIS LOOP BE DONE IN A MORE EFFICIENT/FASTER MANNER? YES 
numCores <- detectCores() # get the number of cores available
cl <- makeCluster(numCores, type = "SOCK")
registerDoSNOW(cl) 

# Function to combine the outputs 
mycombinefunc <-  function(a,b){merge(a, b, by = c("date","open"))}

# Run the loop over multiple cores
meh <- foreach(i = 1825:1830, .combine = "mycombinefunc") %dopar% {
  message(i)
  df %>% 
    # Adjust everything
    tq_mutate(mutate_fun = rollapply,
              width      = window_size,
              by.column  = FALSE,
              FUN        = my_bogus_function,
              col_rename = gsub("$", sprintf(".%d", i), cnames), 
              V0 = i
    )
}
stopCluster(cl)
# END OF THE FOR LOOP I WANTED FASTER
...