我确实想创建一个数据帧,如下所示:
c("V2", "V3" , "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20",
"V3" , "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20",
"V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20",
"V5", "V6", "V7", "V8", "V9", "V10", "V11", "V12", "V13", "V14", "V15", "V16", "V17", "V18", "V19", "V20`",
.
.
.
"V20`")
它必须每次删除第一个项目,直到最后一个项目。
我尝试过使用以下代码,但它重复了每个元素。
x <- rep(sprintf('V%d', 2:20), c(19:1))
有什么建议可以解决这个问题吗?
我们可以使用显式应用函数或循环sequence
:
x[unlist(sapply(2:20, ':', 20))]
如果你想走功能路线进行速度测试,请参阅下面的
#apply function
fun1 <- function(x) {
len <- length(x)
x[unlist(sapply(2:len, function(n) n:len))]
}
#sequence reverse
fun2 <- function(x) {
len <- length(x)
x[rev(c(len, abs(len+1L-sequence(2:(len-1L)))))]
}
#Speed test
x <- paste0("V", 1:1e4)
all.equal(fun1(x), fun2(x))
[1] TRUE
library(microbenchmark)
microbenchmark(
apply = fun1(x),
seq_rev = fun2(x)
)
# Unit: milliseconds
# expr min lq mean median uq max neval cld
# apply 671.8687 792.1317 1020.802 842.7255 991.182 2553.252 100 a
# seq_rev 1335.4235 1551.2272 1829.718 1643.3866 1785.616 4250.515 100 b
sequence
函数在这么多函数调用的情况下速度较慢也就不足为奇了。
您可以试试data.table::shift()
。它是用C语言实现的,所以应该很快。
library(data.table)
c(na.omit(unlist(shift(paste0("V", 1:20), 0:19, type = "lead"))))
保留NA
值不变的其他变体是列表结果。。。
shift(paste0("V", 1:20), 0:19, type = "lead")
或数据表结果。。。
data.table(x = paste0("V", 1:20))[, shift(x, 0:19, type = "lead")]
顺便说一下,在你提到的问题中,你想要一个数据框架。但你展示的实际上是一个原子矢量。
也许不理想,但这个嵌套的for循环完成了任务:
x <- c()
for(i in 2:5) {
for(j in i:5) {
x <- c(x, paste0("V", j))
}
}
x
# [1] "V2" "V3" "V4" "V5" "V3" "V4" "V5" "V4" "V5" "V5"