通过交替步骤在 R 中获取 seq()

Get a seq() in R with alternating steps

R 中的 seq 函数会给我一个从 xy 的序列,其中 constant 步骤 m :

seq(x, y, m)

例如seq(1,9,2) = c(1,3,5,7,9).

使用 交替 步骤 m1 和 [=19] 获得从 xy 的序列的最优雅方法是什么=],这样像 "seq(x, y, c(m1, m2))" 这样的东西会给我 c(x, x + m1, (x + m1) + m2, (x + m1 + m2) + m1, ..., y),每次添加一个步骤(不一定达到 y,当然,如 seq )?

示例:x = 1; y = 19; m1 = 2; m2 = 4 我得到 c(1,3,7,9,13,15,19)

您可以使用

生成此序列的第一个n
x = 1; m1 = 2; m2 = 4

n <- 0:10 # first 11 terms
x + ceiling(n/2)*m1 + ceiling((n-1)/2)*m2
# [1] 1  3  7  9 13 15 19 21 25 27 31

我通过以下方式找到了解决方案: 1. 将 cumsum 与向量 c(from,rep(by,times),...) 一起使用,by 重复 times = ceiling((to-from)/sum(by)) 次。 2.按!(seq > to).

截断序列
 seq_alt <- function(from, to, by) {
   seq <- cumsum(c(from,rep(by,ceiling((to-from)/sum(by)))))
   return(seq[! seq > to])
 }

这是另一个想法,

fun1 <- function(x, y, j, z){
if(j >= y) {return(x)}else{
  s1 <- seq(x, y, j+z)
  s2 <- seq(x+j, y, j+z)
  return(sort(c(s1, s2)))
  }
}

fun1(1, 19, 2, 4)
#[1]  1  3  7  9 13 15 19

fun1(1, 40, 4, 3)
#[1]  1  5  8 12 15 19 22 26 29 33 36 40

fun1(3, 56, 7, 10)
#[1]  3 10 20 27 37 44 54

fun1(1, 2, 2, 4)
#[1] 1

这是一个替代方案,它使用 diffinv 此方法过度分配值,因此作为停止规则,我得到小于或等于停止值的元素。

seqAlt <- function(start, stop, by1, by2) {
   out <- diffinv(rep(c(by1, by2), ceiling(stop / (by1 + by2))), xi=start)
   return(out[out <= stop])
}

seqAlt(1, 19, 2, 4)
[1]  1  3  7  9 13 15 19

R 中回收向量的完美示例

# 1. 
x = 1; y = 19; m1 = 2; m2 = 4
(x:y)[c(TRUE, rep(FALSE, m1-1), TRUE, rep(FALSE,m2-1))]
# [1]  1  3  7  9 13 15 19
# 2.
x = 3; y = 56; m1 = 7; m2 = 10
(x:y)[c(TRUE, rep(FALSE, m1-1), TRUE, rep(FALSE,m2-1))]
# [1]  3 10 20 27 37 44 54

您可以使用 Reduceaccumulate = TRUE 来迭代添加 2 或 4:

Reduce(`+`, rep(c(2,4), 10), init = 1, accumulate = TRUE)
# [1]  1  3  7  9 13 15 19 21 25 27 31 33 37 39 43 45 49 51 55 57 61

重复的次数c(2,4)将决定序列的长度;因为上面是10,所以序列长度是20.

purrr 包有一个 accumulate 包装器,如果您喜欢语法:

purrr::accumulate(rep(c(2,4), 10), `+`, .init = 1)
## [1]  1  3  7  9 13 15 19 21 25 27 31 33 37 39 43 45 49 51 55 57 61