创建数字序列的序列

Ren*_*ene 21 math r vector sequence rep

我想通过使用rep或任何其他函数在 R 中创建以下序列。

c(1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5)
Run Code Online (Sandbox Code Playgroud)

基本上,c(1:5, 2:5, 3:5, 4:5, 5:5)

Maë*_*aël 37

使用sequence

sequence(5:1, from = 1:5)
[1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
Run Code Online (Sandbox Code Playgroud)

第一个参数nvec是每个序列的长度 ( 5:1);第二个from是每个序列 ( ) 的起点1:5

注意:这仅适用于 R >= 4.0.0。来自R 新闻 4.0.0

sequence()[...]获得参数[例如from]以生成更复杂的序列。

  • @Henrik 前段时间使用“sequence”回答了一个非常类似的问题:/sf/answers/4752099481/ (2认同)

Mer*_*org 8

unlist(lapply(1:5, function(i) i:5))
# [1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
Run Code Online (Sandbox Code Playgroud)

对提供的所有答案进行一些速度测试, 如果我没记错的话,请注意OP在某处提到了10K

s1 <- function(n) { 
  unlist(lapply(1:n, function(i) i:n))
}

s2 <- function(n) {
  unlist(lapply(seq_len(n), function(i) seq(from = i, to = n, by = 1)))
}

s3 <- function(n) {
  vect <- 0:n
  unlist(replicate(n, vect <<- vect[-1]))
}

s4 <- function(n) {
  m <- matrix(1:n, ncol = n, nrow = n, byrow = TRUE)
  m[lower.tri(m)] <- 0
  c(t(m)[t(m != 0)])
}

s5 <- function(n) {
  m <- matrix(seq.int(n), ncol = n, nrow = n)
  m[lower.tri(m, diag = TRUE)]
}

s6 <- function(n) {
  out <- c()
  for (i in 1:n) { 
    out <- c(out, (1:n)[i:n])
  }
  out
}

library(rbenchmark)
Run Code Online (Sandbox Code Playgroud)

n = 5

n = 5L

benchmark(
  "s1" = { s1(n) },
  "s2" = { s2(n) },
  "s3" = { s3(n) },
  "s4" = { s4(n) },
  "s5" = { s5(n) },
  "s6" = { s6(n) },
  replications = 1000,
  columns = c("test", "replications", "elapsed", "relative")
)
Run Code Online (Sandbox Code Playgroud)

不要被一些几乎不使用任何需要时间调用的函数的“快速”解决方案所迷惑,并且差异会乘以 1000 倍的复制。

  test replications elapsed relative
1   s1         1000    0.05      2.5
2   s2         1000    0.44     22.0
3   s3         1000    0.14      7.0
4   s4         1000    0.08      4.0
5   s5         1000    0.02      1.0
6   s6         1000    0.02      1.0
Run Code Online (Sandbox Code Playgroud)

n = 1000

n = 1000L

benchmark(
  "s1" = { s1(n) },
  "s2" = { s2(n) },
  "s3" = { s3(n) },
  "s4" = { s4(n) },
  "s5" = { s5(n) },
  "s6" = { s6(n) },
  replications = 10,
  columns = c("test", "replications", "elapsed", "relative")
)
Run Code Online (Sandbox Code Playgroud)

正如海报已经提到的“不要做”,我们看到for与任何其他方法相比,循环变得相当慢,n = 1000L

  test replications elapsed relative
1   s1           10    0.17    1.000
2   s2           10    0.83    4.882
3   s3           10    0.19    1.118
4   s4           10    1.50    8.824
5   s5           10    0.29    1.706
6   s6           10   28.64  168.471
Run Code Online (Sandbox Code Playgroud)

n = 10000

n = 10000L

benchmark(
  "s1" = { s1(n) },
  "s2" = { s2(n) },
  "s3" = { s3(n) },
  "s4" = { s4(n) },
  "s5" = { s5(n) },
  # "s6" = { s6(n) },
  replications = 10,
  columns = c("test", "replications", "elapsed", "relative")
)
Run Code Online (Sandbox Code Playgroud)

在大 n 时,我们看到矩阵与其他方法相比变得非常慢。在 apply 中使用 seq 可能会更简洁,但需要权衡,因为调用该函数 n 次会大大增加处理时间。尽管 seq_len(n) 比 1:n 更好并且只运行一次。有趣的是,复制方法是最快的。

  test replications elapsed relative
1   s1           10    5.44    1.915
2   s2           10    9.98    3.514
3   s3           10    2.84    1.000
4   s4           10   72.37   25.482
5   s5           10   35.78   12.599
Run Code Online (Sandbox Code Playgroud)

  • 具有“sequence”且 n = 10000 的快速“system.time”表明它比“replicate”方法快大约 8-9 倍。 (2认同)

J. *_*ini 5

你提到的rep让我想起了replicate,所以这是一个非常有状态的解决方案。我介绍这个是因为它很短而且不寻常,而不是因为它很好。这是非常不惯用的 R。

vect <- 0:5
unlist(replicate(5, vect <<- vect[-1]))
[1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
Run Code Online (Sandbox Code Playgroud)

rep您可以使用和的组合来完成此操作lapply,但这与 Merijn van Tilborg 的答案基本相同。

当然,真正无所畏惧、单一的 R 用户会这样做,并且拒绝进一步详细说明。

mat <- matrix(1:5, ncol = 5, nrow = 5, byrow = TRUE)
mat[lower.tri(mat)] <- 0
c(t(mat)[t(mat != 0)])
[1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
Run Code Online (Sandbox Code Playgroud)