Невозможно динамически изменять внешние переменные в подпрограмме в R при использовании apply в matix?

#r #variables #apply #dynamically-generated

#r #переменные #применить #динамически генерируемый

Вопрос:

Эта проблема уже пару дней сбивает меня с толку. Допустим, у меня есть две матрицы:

 matrix_a <- matrix(0, nrow = 3, ncol = 3, 
                   dimnames = list(c("r1", "r2", "r3"), c("c1", "c2", "c3")))
matrix_b <- matrix(c("r1", "r2", "c1", "c2"), nrow = 2, ncol = 2)
  

Я хочу динамически изменять matrix_a в функции:

 change_var <- function(x, matrix_a) {
    if(any(rownames(matrix_a) == x[1])  amp;amp; any(colnames(matrix_a) == x[2])) {
        matrix_a[x[1], x[2]] <- 1
        return (matrix_a)
    }
}
apply(matrix_b, 1, change_var, matrix_a)
  

однако, похоже, что этот код вообще не может изменить matrix_a . Но мой предполагаемый результат matrix_a должен быть

    c1 c2 c3
r1  1  0  0
r2  0  2  0
r3  0  0  0
  

Как мы могли бы достичь цели динамического изменения matrix_a ? Пожалуйста, предоставьте мне решение, не предназначенное для цикла. Заранее спасибо.

Комментарии:

1. Аргументы функции передаются по значению, вот почему оригинал matrix_a не изменяется. Кроме того, apply вероятно, это будет не быстрее, чем хорошо написанный цикл for.

2. Я думаю, что нашел правильный ответ прямо сейчас.

3. @Joshua Использует <<- операцию

4. <<- выполняет поиск объекта, которому вы присваиваете, и присваивает глобальной среде, если объект не может быть найден. Возможно, вы захотите быть более явным и использовать assign(..., envir=.GlobalEnv) .

5. Как в результате получилось 2 ? Ваша change_var функция присваивает значения только 1 ячейкам? Вы имели в виду увеличение значения ячейки?

Ответ №1:

Как вы уже знаете, <<- or assign можно использовать для изменения «глобальной» переменной. <<- очень похоже на вызов assign с inherits=TRUE помощью.

…но, похоже, вы пытаетесь создать матрицу, которая подсчитывает количество вхождений координат ячеек, заданных matrix_b? Это более эффективно выполняется (без циклов for!) с помощью table функции. Я добавил дублирующуюся строку в matrix_b , чтобы показать, что это работает:

 matrix_a <- matrix(0, nrow = 3, ncol = 3, 
                   dimnames = list(c("r1", "r2", "r3"), c("c1", "c2", "c3")))
matrix_b <- matrix(c("r1", "r2", "r2", "c1", "c2", "c2"), nrow = 3, ncol = 2)
# Convert matrix_b from 2-d to 1-d indices
row <- match(matrix_b[,1], rownames(matrix_a))
col <- match(matrix_b[,2], colnames(matrix_a))
idx <- row (col-1)*nrow(matrix_a)
# Then count the number of identical indices using table
matrix_a[sort(unique(idx))] <- table(idx)
  

Какие обновления matrix_a для:

    c1 c2 c3
r1  1  0  0
r2  0  2  0
r3  0  0  0
  

…конечно, если вам нужно только вставить 1 туда, вам не нужно вызывать table :

 row <- match(matrix_b[,1], rownames(matrix_a))
col <- match(matrix_b[,2], colnames(matrix_a))
idx <- row (col-1)*nrow(matrix_a)
matrix_a[idx] <- 1