Замена каждой строки в матрице - PullRequest
4 голосов
/ 13 августа 2011

У меня есть матрица (mat1), скажем, 100 строк и 100 столбцов; Я хочу создать другую матрицу, в которой каждая строка совпадает с 1-й строкой в ​​mat1 (за исключением того, что я хочу сохранить 1-й столбец в качестве исходных значений)

Мне удалось сделать это с помощью цикла:

mat2 <- mat1

for(i in 1:nrow(mat1))
{
    mat2[i,2:ncol(mat2)] <- mat1[1,2:ncol(mat1)]
}

это работает и дает ожидаемый результат; однако я бы подумал, что должен быть способ сделать это без цикла; Я пробовал:

mat2 <- mat1
mat2[c(2:100),2:ncol(mat2)] <- mat1[1,2:ncol(mat1)]

Может кто-нибудь указать на мою ошибку?!

Спасибо
Chris

Ответы [ 3 ]

8 голосов
/ 13 августа 2011

Проблема в том, как R заполняет матрицы столбцами.Вот простой пример, который иллюстрирует это:

mat1 <- matrix(1:9, ncol = 3)
mat2 <- matrix(1:9, ncol = 3)

mat2[-1, -1] <- mat1[1, -1]
mat2

> mat2
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    4    4
[3,]    3    7    7

mat1[1, -1] - это вектор 4,7, который, как вы можете видеть, R использовал для заполнения бита mat2 по столбцам.Вы хотели построчную операцию.

Одним из решений является репликация вектора замены столько раз, сколько требуется:

> mat2[-1, -1] <- rep(mat1[1, -1], each = nrow(mat1)-1)
> mat2
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    4    7
[3,]    3    4    7

Это работает, потому что вызов rep() реплицирует каждое значение ввектор, когда мы используем аргумент "each" вместо репликации (повторения) вектора:

> rep(mat1[1, -1], each = nrow(mat1)-1)
[1] 4 4 7 7

Поведение по умолчанию также даст неправильный ответ:

> rep(mat1[1, -1], nrow(mat1)-1)
[1] 4 7 4 7

Частичнопроблема, с которой вы сталкиваетесь, заключается также в том, что R расширяет аргументы до соответствующей длины для замены.R фактически и молча расширял вектор замены точно так же, как это делает rep(mat1[1, -1], nrow(mat1)-1), что в сочетании с принципом заполнения по столбцу давало поведение, которое вы видели.

1 голос
/ 14 августа 2011

Другой вариант ...

n = 5
mat1 = matrix(sample(n^2, n^2), n, n)

# use matrix with byrow to copy 1st row n times
mat2 = matrix(rep(mat1[1, ], n), n, n, byrow = TRUE)

# copy 1st column 
mat2[ , 1] = mat1[ , 1]

mat1
mat2
1 голос
/ 13 августа 2011

Попробуйте

mat2[c(2:nrow(mat2)), 2:ncol(mat2)] <- mat1[rep.int(1,nrow(mat1)-1),2:ncol(mat1)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...