模仿Matlab矩阵行为

时间:2015-11-09 17:34:14

标签: r

我在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的方式吗?

1 个答案:

答案 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