Динамическое кодирование непрерывных переменных в R data.table - PullRequest
1 голос
/ 15 мая 2019

У меня есть data.table DT с двумя переменными start и end, которые я хотел бы кодировать с использованием динамического вектора. start и end - это некие непрерывные или порядковые переменные (в данном примере целые числа для простоты использования). Динамический вектор содержит динамически выбранные точки данных в пространстве начала и конца. Я хотел бы закодировать таблицу данных на основе вектора.

> DT <- data.table(cust = c('A', 'A', 'B', 'C')
                 , start = c(1,6,2,2)
                 , end = c(4,8,5,10))
> DT
   cust start end
1:    A     1   4
2:    A     6   8
3:    B     2   5
4:    C     2  10

> dynamic_vector <- c(2,5,7,11)

каждый добавленный столбец основан на элементах динамического вектора. значение столбца start_dynamic_vector [i] равно 1, если start <= dynamic_vector [i] и dynamic_vector [i] <= end. </p>

Я могу сделать это с помощью цикла for:

> for (i in dynamic_vector) DT[, (paste0('month_', i)) := (i >= start & end >= i) + 0L]
> DT
   cust start end month_2 month_5 month_7 month_11
1:    A     1   4       1       0       0        0
2:    A     6   8       0       0       1        0
3:    B     2   5       1       1       0        0
4:    C     2  10       1       1       1        0

как я могу сделать это без использования цикла for? Я имею дело с двумя непрерывными переменными начала и конца. динамический вектор может быть довольно большим (несколько сотен элементов). DT также является относительно большой таблицей (около 50 миллионов записей). цикл длится долго!

1 Ответ

2 голосов
/ 15 мая 2019

Используйте %between% и Map, затем присвойте := все выходные переменные одновременно:

DT[
  ,
  paste0("month_", dynamic_vector) := lapply(
    Map(`%between%`, dynamic_vector, .(.(start,end))), as.integer
  )
]

#   cust start end month_2 month_5 month_7 month_11
#1:    A     1   4       1       0       0        0
#2:    A     6   8       0       0       1        0
#3:    B     2   5       1       1       0        0
#4:    C     2  10       1       1       1        0
...