Я имею в виду решение 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
Если вы хотите go еще быстрее, вы можно установить ключ (?setkeyv
). Если ваш фрейм данных имеет значительный размер, это может привести к значительному увеличению производительности (в этом небольшом примере это не так)