将数字范围扩大到单个数字

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

不知道该如何给这个问题起标题,如果有更好的建议请自行编辑


比如说我们有这样一个数据框架。

数据集

df <- data.frame(start = c(10, 20), end = c(15,33), label = c('ex1','ex2'))

这看起来像这样。

  start end label
1    10  15   ex1
2    20  33   ex2

我想得到什么 我想扩大从 start --> end,像这样。

  pos label
1   10   ex1
2   11   ex1
3   12   ex1
4   13   ex1
5   14   ex1
6   15   ex1
7   20   ex2
8   21   ex2
9   22   ex2
10  23   ex2
11  24   ex2
12  25   ex2
13  26   ex2
14  27   ex2
15  28   ex2
16  29   ex2
17  30   ex2
18  31   ex2
19  32   ex2
20  33   ex2

我现在有什么

f <- function(x) {data.frame(pos = x$start:x$end, label = x$label)}
df %>% rowwise() %>% do(f(.))

虽然我的解决方案可行,但我的原始数据集要大得多,怀疑这样做是否有效。此外,我希望包含更多的列,而不是 label 所以,我想重新训练所有的列,只是分散的。startend

r dataframe expand
2个回答
1
投票

我有一个 data.table 心中的解决方案。

我做了一个假设,你的 label var通过观察是唯一的。否则,你应该使用一个行号来分组数据。

library(data.table)
df <- data.frame(start = c(10, 20), end = c(15,33), label = c('ex1','ex2'))
setDT(df)

df[, seq(.SD[['start']], .SD[['end']]), by = label]
label V1
 1:   ex1 10
 2:   ex1 11
 3:   ex1 12
 4:   ex1 13
 5:   ex1 14
 6:   ex1 15
 7:   ex2 20
 8:   ex2 21
 9:   ex2 22
10:   ex2 23
11:   ex2 24
12:   ex2 25
13:   ex2 26
14:   ex2 27
15:   ex2 28
16:   ex2 29
17:   ex2 30
18:   ex2 31
19:   ex2 32
20:   ex2 33

就效率而言,可能很难找到一个比以下方法更快的解决方案 data.table 是为此目的而设计的。

如果你不能使用 label 作为一个唯一的标识符,你可以做

df[,'rn' := seq(.N)]

df[, seq(.SD[['start']], .SD[['end']]), by = c('rn','label')]
    rn label V1
 1:  1   ex1 10
 2:  1   ex1 11
 3:  1   ex1 12
 4:  1   ex1 13
 5:  1   ex1 14
 6:  1   ex1 15
 7:  2   ex2 20
 8:  2   ex2 21
 9:  2   ex2 22
10:  2   ex2 23
11:  2   ex2 24
12:  2   ex2 25
13:  2   ex2 26
14:  2   ex2 27
15:  2   ex2 28
16:  2   ex2 29
17:  2   ex2 30
18:  2   ex2 31
19:  2   ex2 32
20:  2   ex2 33

并且您可以使用以下方法删除中间行号 df[,'rn' := NULL]

效益

data.table 带来了很好的加速(在这个例子中,如果你使用一列或两列来分组,这并不重要

Unit: microseconds
                                                           expr      min       lq     mean   median       uq
                                  df %>% rowwise() %>% do(f(.)) 1549.408 1808.669 2309.332 2292.525 2555.888
          df[, seq(.SD[["start"]], .SD[["end"]]), by = "label"] 1011.608 1302.249 1555.808 1490.542 1779.543
 df[, seq(.SD[["start"]], .SD[["end"]]), by = c("label", "rn")]  968.124 1095.703 1387.556 1253.023 1592.483
      max neval cld
 7141.964   100   b
 3061.487   100  a 
 2953.598   100  a 

如果你想走得更快,你可以设置一个键(?setkeyv). 如果你的数据帧有很大的规模,这可能会带来巨大的性能提升(在这个小例子中,它不会

© www.soinside.com 2019 - 2024. All rights reserved.