将号码范围扩展到单个号码
Expand number range to the individual numbers
不确定如何给这个问题起标题所以如果有更好的建议请编辑
假设我们有这个数据框:
数据集
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
)。如果您的数据框很大,这可能会带来巨大的性能提升(在这个小例子中不会)
不确定如何给这个问题起标题所以如果有更好的建议请编辑
假设我们有这个数据框:
数据集
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
)。如果您的数据框很大,这可能会带来巨大的性能提升(在这个小例子中不会)