#r #loops #matrix #apply
#r #циклы #матрица #применить
Вопрос:
После нескольких часов поиска я обращаюсь к вашему опыту. Новичок в R, я пытаюсь ускорить свой код. Моя цель — заменить значения в матрице A
. Однако я хочу заменить значения на основе двух векторов другой матрицы B
. B[, 1]
— это имя строки i
матрицы A
. Второй столбец B[, 2]
соответствует имени столбца матрицы A
.
Первая версия моего кода заключалась в использовании функции сопоставления в цикле.
for(k in 1:L){
i <- B[k,1]
j <- B[k,2]
d <- match(i,rownames(A))
e <- match(j,colnames(A))
A[d, e] <- 0
}
Вторая версия позволила мне немного ускорить:
for( k in 1:L) {
A[match(B[k,1],rownames(A)), match(B[k,2],colnames(A))] <- 0
}
Однако время обработки велико, слишком велико. Поэтому я решил использовать apply
функцию. Для этого я должен использовать apply
в каждой строке векторы B
.
Является ли использование apply
функции отличным способом? Или я иду не тем путем?
Ответ №1:
Мне кажется, что вы можете просто сделать A[B[, 1:2]] <- 0
, используя возможности индексации матрицы.
Например, A[cbind(1:4, 1:4)] <- 0
заменит A[1,1]
, A[2,2]
, A[3,3]
и A[4,4]
на 0 . Фактически, if A
имеет атрибуты «dimnames» («имена строк» и «имена столбцов», на которые вы ссылаетесь), мы также можем использовать символьные строки в качестве индекса.
Воспроизводимый пример
A <- matrix(1:16, 4, 4, dimnames = list(letters[1:4], LETTERS[1:4]))
# A B C D
#a 1 5 9 13
#b 2 6 10 14
#c 3 7 11 15
#d 4 8 12 16
set.seed(0); B <- cbind(sample(letters[1:4])), sample(LETTERS[1:4]))
# [,1] [,2]
#[1,] "d" "D"
#[2,] "a" "A"
#[3,] "c" "B"
#[4,] "b" "C"
## since `B` has just 2 columns, we can use `B` rather than `B[, 1:2]`
A[B] <- 0
# A B C D
#a 0 5 9 13
#b 2 6 0 14
#c 3 0 11 15
#d 4 8 12 0