不知道该如何给这个问题起标题,如果有更好的建议请自行编辑
比如说我们有这样一个数据框架。
数据集
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
所以,我想重新训练所有的列,只是分散的。start
和 end
我有一个 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
). 如果你的数据帧有很大的规模,这可能会带来巨大的性能提升(在这个小例子中,它不会