我想知道在某个索引拆分载体分为两个简单的任务:
splitAt <- function(x, pos){
list(x[1:pos-1], x[pos:length(x)])
}
a <- c(1, 2, 2, 3)
> splitAt(a, 4)
[[1]]
[1] 1 2 2
[[2]]
[1] 3
我的问题:必须有一些这方面的现有功能,但我不能找到它? 也许是split
的可能性? 我的幼稚实施也不起作用如果pos=0
或pos>length(a)
我想知道在某个索引拆分载体分为两个简单的任务:
splitAt <- function(x, pos){
list(x[1:pos-1], x[pos:length(x)])
}
a <- c(1, 2, 2, 3)
> splitAt(a, 4)
[[1]]
[1] 1 2 2
[[2]]
[1] 3
我的问题:必须有一些这方面的现有功能,但我不能找到它? 也许是split
的可能性? 我的幼稚实施也不起作用如果pos=0
或pos>length(a)
的改进是:
splitAt <- function(x, pos) unname(split(x, cumsum(seq_along(x) %in% pos)))
现在可以采取位置的矢量:
splitAt(a, c(2, 4))
# [[1]]
# [1] 1
#
# [[2]]
# [1] 2 2
#
# [[3]]
# [1] 3
和它不正确地 (主观)表现如果pos <= 0
或pos >= length(x)
在它返回在单个列表项整个原始矢量感。 如果你想它,而不是错误的,使用stopifnot
在函数的顶部。
我试图用flodel的答案 ,但在我的情况是太慢了一个非常大的x
(和函数反复调用)。 所以,我创建了以下功能要快得多,但也很丑陋,工作不正常。 特别是,它不检查任何东西,将至少返回马车结果pos >= length(x)
或pos <= 0
(你可以自己,如果你不确定你的投入并没有太在意速度添加这些检查),也许还有其他一些情况下为好,所以要小心。
splitAt2 <- function(x, pos) {
out <- list()
pos2 <- c(1, pos, length(x)+1)
for (i in seq_along(pos2[-1])) {
out[[i]] <- x[pos2[i]:(pos2[i+1]-1)]
}
return(out)
}
然而, splitAt2
运行具有长度为10 6的x约快20倍:
library(microbenchmark)
W <- rnorm(1e6)
splits <- cumsum(rep(1e5, 9))
tm <- microbenchmark(
splitAt(W, splits),
splitAt2(W, splits),
times=10)
tm
另一种方法可能比更快和/或更可读/优雅flodel的解决方案 :
splitAt <- function(x, pos) {
unname(split(x, findInterval(x, pos)))
}