Эффективное хранение наборов данных с большим количеством предварительно скомпилированных переменных (и когда можно использовать только несколько)

Я пишу приложение Shiny, в котором читается большой набор данных, и некоторые анализы выполняются в зависимости от ввода пользователя. Эти анализы основаны на переменной y которая может быть преобразована из другой переменной x зависимости от значения k введенного пользователем.

Проблема здесь в том, что этот шаг преобразования требует времени, поэтому сейчас все возможные значения y предварительно вычислены. Рассмотрим следующий упрощенный пример:

set.seed(1234)
data <- tibble (x = rnorm(n = 10, mean = 5, sd = 1) )

k_vector <- seq(from=1,to=3,by=1)

for (k in k_vector) {
  new_col = stringr::str_c("y",k)
  data <- dplyr::mutate(data, !!new_col := x*k)
}

Что приводит к следующей таблице:

   x    y1    y2    y3
<dbl> <dbl> <dbl> <dbl>
1  3.79  3.79  7.59 11.4 
2  5.28  5.28 10.6  15.8 
3  6.08  6.08 12.2  18.3 
4  2.65  2.65  5.31  7.96
5  5.43  5.43 10.9  16.3 
6  5.51  5.51 11.0  16.5 
7  4.43  4.43  8.85 13.3 
8  4.45  4.45  8.91 13.4 
9  4.44  4.44  8.87 13.3 
10  4.11  4.11  8.22 12.3

Затем я .rda эту таблицу как .rda и прочту ее из блестящего приложения. Тогда я бы включил команду типа dplyr::transmute(data,x=x,y=y1) (если в данном случае k = 1) в реактивную область, так что в любое время, когда пользователь изменяет значение k новая переменная y выбран. Как вы можете себе представить, это решило проблему преобразования формы x в y заданном k .

Но если реальный набор данных и / или число возможных значений k велико, то сохраненная таблица будет ОГРОМНОЙ, поэтому это становится проблемой не только для хранения, но и для времени при ее чтении. Я избегаю создания N баз данных, по одной на значение k , в надежде, что есть более эффективный способ выполнить эту задачу. Есть идеи?

Всего 1 ответ


Это будет зависеть от вашего фактического варианта использования, но библиотека ( data.table ) часто является хорошим местом для начала, с точки зрения производительности в R:

library(dplyr)
library(data.table)
library(microbenchmark)

set.seed(1234)
data <- tibble(x = rnorm(n = 10, mean = 5, sd = 1))
DT <- setDT(data)

k_vector <- seq(from = 1, to = 3, by = 1)

results <- microbenchmark("dplyr" = {
  for (k in k_vector) {
    new_col = stringr::str_c("y", k)
    data <- dplyr::mutate(data, !!new_col := x * k)
  }
}, "data.table" = {
  DT[, paste0("y", k_vector) := lapply(k_vector, "*", x)]
})

results

Результаты:

Unit: microseconds
       expr      min       lq      mean   median       uq       max neval
      dplyr 3544.318 4039.898 5514.8110 4622.190 5995.553 13434.590   100
 data.table  355.933  415.584  667.1352  519.678  637.400  4388.128   100

Есть идеи?

10000