如何在R中生成一个向量的所有可能的连续n元组?第一个
acruukt91#
我们可以删除第一个和最后一个元素,并通过使用Map循环相应的元素来连接
Map
Map(c, x[-length(x)], x[-1]) $a [1] "a" "b" $b [1] "b" "c" $c [1] "c" "b"
或者将cbind转换为matrix,并使用asplit按行拆分
cbind
matrix
asplit
asplit(cbind(x[-length(x)], x[-1]), 1) [[1]] [1] "a" "b" [[2]] [1] "b" "c" [[3]] [1] "c" "b"
如果n的值可以大于2,我们也可以用shift来实现
n
shift
library(data.table) Filter(\(x) all(complete.cases(x)), data.table::transpose(shift(x, seq_len(n)-1, type = 'lead'))) [[1]] [1] "a" "b" [[2]] [1] "b" "c" [[3]] [1] "c" "b"
0qx6xfy62#
Vectorized BaseR解决方案(我不使用embed或asplit;它们内部具有for-循环)。第一个你能简化这个函数吗?删除format。直截了当的一行字:
embed
for
format
split(x[sequence(rep(length(x) - n + 1, n), 1:n)], seq_len(length(x) - n + 1))
rt4zxlrg3#
这里有些好玩的。
fun1 <- function (x, n) asplit(embed(x, n)[, n:1], 1) fun2 <- function (x, n) split(x[sequence(rep(length(x) - n + 1, n), 1:n)], seq_len(length(x) - n + 1)) fun3 <- function (x, n) lapply(1:(length(x) - n + 1), \(i) x[i:(i + n - 1)]) library(microbenchmark) x <- 1:10000 microbenchmark("for" = fun1(x, 2), "split" = fun2(x, 2), "lapply" = fun3(x, 2)) #Unit: milliseconds # expr min lq mean median uq max neval cld # for 30.536090 39.196876 49.400427 48.541195 55.481533 107.46441 100 c # split 6.453484 7.049844 7.765709 7.647299 7.904683 13.63022 100 a # lapply 16.070532 21.959815 26.988959 28.482102 31.133325 45.47318 100 b microbenchmark("for" = fun1(x, 10), "split" = fun2(x, 10), "lapply" = fun3(x, 10)) #Unit: milliseconds # expr min lq mean median uq max neval cld # for 34.115408 34.826142 39.136366 35.631689 37.200893 200.63875 100 c # split 8.566762 8.780026 9.255456 9.057524 9.641736 12.67383 100 a # lapply 17.343556 17.845281 19.289687 18.301174 18.833777 28.19920 100 b microbenchmark("for" = fun1(x, 20), "split" = fun2(x, 20), "lapply" = fun3(x, 20)) #Unit: milliseconds # expr min lq mean median uq max neval cld # for 38.33747 38.90368 40.61395 39.72388 40.64009 51.51035 100 c # split 11.29013 11.39768 12.07148 11.48208 12.13088 17.46919 100 a # lapply 18.77825 18.94005 20.88440 19.33751 19.93676 42.35469 100 b
lx0bsm1f4#
lapply(1:(length(x) - n + 1), \(i) x[i:(i + n - 1)]) # [[1]] # [1] "a" "b" # [[2]] # [1] "b" "c" # [[3]] # [1] "c" "b"
4条答案
按热度按时间acruukt91#
我们可以删除第一个和最后一个元素,并通过使用
Map
循环相应的元素来连接或者将
cbind
转换为matrix
,并使用asplit
按行拆分如果
n
的值可以大于2,我们也可以用shift
来实现0qx6xfy62#
Vectorized BaseR解决方案(我不使用
embed
或asplit
;它们内部具有for
-循环)。第一个
你能简化这个函数吗?删除
format
。直截了当的一行字:
rt4zxlrg3#
这里有些好玩的。
lx0bsm1f4#