我想通過使用rep或任何其他功能在 R 中制作以下序列。
c(1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5)
基本上,c(1:5, 2:5, 3:5, 4:5, 5:5).
uj5u.com熱心網友回復:
使用sequence.
sequence(5:1, from = 1:5)
[1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
第一個引數 ,nvec是每個序列的長度 ( 5:1);第二個 ,from是每個序列 ( 1:5)的起點。
注意:這僅適用于 R >= 4.0.0。從R 新聞 4.0.0:
sequence()[...] 獲得引數 [egfrom] 以生成更復雜的序列。
uj5u.com熱心網友回復:
unlist(lapply(1:5, function(i) i:5))
# [1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
如果我沒記錯的話,對所有答案提供的一些速度測驗請注意 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)
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")
)
不要被一些“快速”的解決方案所迷惑,這些解決方案幾乎不使用任何需要時間來呼叫的函式,并且差異會乘以 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
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")
)
正如海報已經提到的“不要做”,我們看到for與任何其他方法相比,回圈變得非常慢,onn = 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
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")
)
在大 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
uj5u.com熱心網友回復:
你提到的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
您可以使用repand的組合來做到這一點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
uj5u.com熱心網友回復:
你可以使用這樣的回圈:
out=c();for(i in 1:5){ out=c(out, (1:5)[i:5]) }
out
# [1] 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
但這不是一個好主意!
為什么不使用回圈?
使用回圈是:
- 慢點,
- 記憶體效率較低,并且
- 更難閱讀和理解。
相比之下,使用矢量化函式sequence則相反(更快、更高效且易于閱讀)。
更多資訊
來自?sequence:
序列的默認方法為并行(和回收)向量中的
seq(from[i], by = by[i], length.out = nvec[i])每個元素生成序列,并且。然后它回傳連接這些序列的結果。ifrombynvec
關于from論點:
from:每個元素指定序列的第一個元素。
此外,由于回圈中使用的向量沒有預先分配,它將需要更多的記憶體,并且也會更慢。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/406027.html
標籤:
上一篇:根據負面和正面計算聲譽百分比
下一篇:繪制位模式時連續兩個錯誤
