将数据表中的单个值分解为值为1的行

问题描述 投票:1回答:2

我正在创建一个虚拟数据集,该数据集基于已知的离散分布(基本MC采样)生成值duration(如下)。每个持续时间都分配给一个连续的id号。使用rnorm()的简单示例可能如下所示:

set.seed(135813) # whimsical seed
id_dt <- data.table(id = 1:6) # Six "id" numbers
duration_dt <- data.table(duration = abs(rnorm(6, mean = 20, sd = 10))) # Sample of six arbitrary positive values
id_durs <- id_dt[, .(id = id, duration = round(duration_dt$duration))] # combine the above DTs; round values to ints

对于duration数据表中的每个id_durs值,我需要将该值表示为1的总和-也就是说,在新行中分配一个值1(映射到ID和原始持续时间),直到创建的位数等于原始值。在此示例中,我们将从以下位置开始:

    id    duration
    --    --------
     1       7
     2      34
     3      33
     4       2
     5      40
     6      27

期望的结果是:

    id    duration    count
    --    --------    -----
     1       7          1
     1       7          1
     1       7          1
     1       7          1
     1       7          1
     1       7          1
     1       7          1      <== duration = 7, Rows = 7
     2      34          1
     2      34          1
     2      34          1
     2      34          1
     2      34          1
     2      34          1
     2      34          1
     2      34          1     
    ...    ...        ...     <== duration = 34, Rows = 34
     3      33          1     
    ...    ...        ...     <== duration = 33, Rows = 33
     4       2          1
     4       2          1     <== duration = 2, Rows = 2
     5      40          1
    ...    ...        ...     <== duration = 40, Rows = 40
     6      27          1
    ...    ...        ...     <== duration = 27, Rows = 27

我知道分解单个值(冗长)的一种方法是:

stuff = 50.4
decomp <- lapply(1:round(stuff), function(i) i <- 1)
result <- data.table(count = unlist(decomp))

但是当尝试将其映射到id和原始值时,我遇到了麻烦。我崩溃了,尝试了一个for循环作为拐杖。适用于以上:

for (i in 1:length(id_durs))
     {
       id_dur_val <- data.table(id = id_durs$id, 
                                duration = id_durs$duration,  
                                count = rep(1, each = id_durs$duration[i]))
      }

但是,这给了我一个等于原始数据中元素数量的重复。我也尝试使用expand.grid(),但是仅将第一个元素(如预期的那样)用作迭代器-因此,每个行的计数对于duration的每个值都是相同的。

这感觉像是一个微不足道的问题,所以我知道我正在忽略某些东西。

谢谢您的任何建议。

r
2个回答
0
投票

为什么不首先添加count列,然后根据需要用rep扩展行:

library(data.table)

id_durs[, count := 1][rep(id, duration), ]
#>      id duration count
#>   1:  1        7     1
#>   2:  1        7     1
#>   3:  1        7     1
#>   4:  1        7     1
#>   5:  1        7     1
#>  ---                  
#> 139:  6       27     1
#> 140:  6       27     1
#> 141:  6       27     1
#> 142:  6       27     1
#> 143:  6       27     1

0
投票

您可以执行以下操作

  duration_dt[,.(count = rep(numeric(.N) + 1, duration)), by = duration]

     duration count
  1:        7     1
  2:        7     1
  3:        7     1
  4:        7     1
  5:        7     1
 ---               
139:       27     1
140:       27     1
141:       27     1
142:       27     1
143:       27     1

推荐问答