我在Matlab中可以垂直向向量添加元素,即使它们的索引范围远远超出下一行。例如:
1 2 3 4 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 2 3 4 5
将返回。
{{1}}
在R中有这么好的,不那么hacky的方式吗?
答案 0 :(得分:4)
虽然joran在切换到R时可能正确地改变你的程序,但你可以利用索引向量导致扩大的事实,正如弗兰克在评论中指出的那样。利用矩阵是具有" dim"属性和 - 为了方便 - 使用矩阵的列式存储,你可以使用类似的东西:
add_col = function(x, col, value)
{
nr = NROW(x)
nc = if(col > NCOL(x)) col else NCOL(x)
i1 = nr * (col - 1) + 1
i2 = i1 + length(value) - 1
x[i1:i2] = value
length(x) = nr * nc
dim(x) = c(nr, nc)
return(x)
}
test = 1:5
add_col(test, 3, 1:3)
# [,1] [,2] [,3]
#[1,] 1 NA 1
#[2,] 2 NA 2
#[3,] 3 NA 3
#[4,] 4 NA NA
#[5,] 5 NA NA
t(add_col(add_col(test, 3, 1:3), 6, 4:1))
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 2 3 4 5
#[2,] NA NA NA NA NA
#[3,] 1 2 3 NA NA
#[4,] NA NA NA NA NA
#[5,] NA NA NA NA NA
#[6,] 4 3 2 1 NA
这可能有点hacky但是并没有比将一个向量索引越界更慢:
X = seq_len(1e5)
microbenchmark::microbenchmark(add_col(X, 1e2, seq_along(X)),
t(add_col(X, 1e2, seq_along(X))), #with a transpose
"[<-"(X, (1e7 - (length(X) - 1)):1e7, seq_along(X)), #just vector out-of-bounds indexing
times = 50)
#Unit: milliseconds
# expr min lq median uq max neval
# add_col(X, 100, seq_along(X)) 34.79408 40.02492 45.61020 63.24266 78.48069 50
# t(add_col(X, 100, seq_along(X))) 79.81389 84.06544 87.57906 102.75845 110.72842 50
# `[<-`(X, (1e+07 - (length(X) - 1)):1e+07, seq_along(X)) 17.25123 18.06138 21.48956 24.69084 48.91988 50
identical(c(add_col(X, 1e2, seq_along(X))), "[<-"(X, (1e7 - (length(X) - 1)):1e7, seq_along(X)))
#[1] TRUE