首页 > 解决方案 > R data.table中连续变量的动态编码

问题描述

我有一个带有两个变量 start 和 end 的 data.table DT,我想使用动态向量对其进行编码。start 和 end 都是某种连续或有序变量(为了便于使用,本例中为整数)。动态向量包含在开始和结束空间中动态选择的数据点。我想根据向量对 data.table 进行编码。

> 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] 且 dynamic_vector[i] <= end,则列 start_dynamic_vector[i] 的值为 1。

我可以使用 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也是一个比较大的表(约50M条目)。for循环需要很长时间!

标签: rfor-loopdynamicencodingdata.table

解决方案


使用%between%and 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

推荐阅读