2015-11-09 5 views
2

I Matlab можно добавлять элементы по вертикали в вектор, хотя их область индекса далеко за пределами следующей строки. Например:Имитировать поведение Matlab Matrix

test = 1:5; 
test(5,:) = 1:5; 

вернется.

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 

Есть ли хороший, не такой хакерский способ сделать это в R?

+1

Нет, это не выполнимая вещь в R. Вы можете сделать это с помощью векторов 'v = 1: 3; v [6] = 4', но больше ничего. Вероятно, вы захотите ознакомиться с некоторыми вводными материалами по R. Лучшая практика заключается в том, чтобы предварительно распределить свою матрицу. – Frank

+0

'm <- матрица (0, 5, 5); m [1,] <- 1: 5; m [5,] <- 1: 5' не знаю, как это полезно, но – rawr

+0

Итак, если мне нужно это сделать, мне нужно будет написать свою собственную функцию, которая обрабатывает все особые случаи? – hfjn

ответ

4

Хотя joran, вероятно, прав насчет изменения вашей процедуры при переключении на R, вы можете использовать тот факт, что индексирование вектора приводит к увеличению, как заметил Фрэнк в комментариях. Пользуясь, что матрицы являются векторы с атрибутом «затемнить» и -для convenience-, используя по-колонки для хранения матриц, вы могли бы использовать что-то вроде:

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