Как создать несколько матриц на основе формулы с использованием двух фреймов данных и просуммировать эти матрицы за один раз?

#r #matrix

#r #матрица

Вопрос:

Я довольно новичок в R и, следовательно, еще не настолько хорошо осведомлен о его различных функциональных возможностях. Мне интересно, есть ли более эффективный способ повторить следующее, кроме написания и выполнения 230 строк кода.

У меня есть две матрицы, Z и E, которые содержат непрерывные числовые данные и имеют размеры 7×229 и 17×229 соответственно. Для каждого столбца (таким образом, 229 раз) Я хочу создать новую матрицу 119×119, используя (повторяющуюся) формулу ниже

 ZZEE1 <- kronecker((Z[,1] %*% t(Z[,1])), (E[,1] %*% t(E[,1])))
ZZEE2 <- kronecker((Z[,2] %*% t(Z[,2])), (E[,2] %*% t(E[,2])))
ZZEE3 <- kronecker((Z[,3] %*% t(Z[,3])), (E[,3] %*% t(E[,3])))
ZZEE4 <- kronecker((Z[,4] %*% t(Z[,4])), (E[,4] %*% t(E[,4])))
#...
ZZEE228 <- kronecker((Z[,228] %*% t(Z[,228])), (E[,228] %*% t(E[,228])))
ZZEE229 <- kronecker((Z[,229] %*% t(Z[,229])), (E[,229] %*% t(E[,229])))
  

После того, как это будет сделано, я хочу сложить все 229 матриц в одну матрицу, подобную этой (не полную)

 Sum_ZZEE <- ZZEE1   ZZEE2   ZZEE3   ZZEE4   ZZEE228   ZZEE229 #Sum of all matrices from ZZEE1 to ZZEE229 
  

Есть ли более быстрое решение, которое сделает именно это? Я пытался найти ответ в Интернете, но не нашел ничего, что работало бы или что-то, что я понимал в той степени, в которой я мог бы изменить это для своих собственных данных / кода. Насколько я понял, возможно, есть исправление с функцией function (), но я бы не знал, как правильно ее закодировать. Получение матрицы ‘Sum_ZZEE’ является конечной целью, мне не обязательно нужны отдельные матрицы, хранящиеся в рабочей области. Премного благодарен!

Ответ №1:

Сначала создайте список матриц: следующие два фрагмента кода эквивалентны, используйте тот, который вам понятнее.

 ZZ_list <- lapply(1:229,
               function(i) kronecker((Z[,i] %*% t(Z[,i])), (E[,i] %*% t(E[,i])))
            )
  

или

 ZZ_list <- list()
for (i in 1:229) {
     ZZ_list[[i]] <- kronecker((Z[,i] %*% t(Z[,i])), (E[,i] %*% t(E[,i])))
}
  

Затем используйте Reduce() (к сожалению sum() , работает не так, как вы хотите):

 answer <- Reduce(" ", ZZ_list)
  

Может быть какой-то суперумный ответ, который работает в чистой линейной алгебре (например, с операторами стекирования / разархивирования)…

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

1. Большое тебе спасибо, Бен!

2. кстати, tcrossprod(Z[,i], Z[,i]) это более эффективная форма x %*% t(x)