En R, ¿hay una forma más eficiente y / o general de producir el resultado deseado a partir de las dos matrices siguientes? Sospecho que lo que he hecho es solo una operación esotérica de multiplicación de matrices de la que no estoy al tanto.

ff <- matrix(1:6,ncol=2)
# [,1] [,2]
# [1,]    1    4
# [2,]    2    5
# [3,]    3    6

bb <- matrix(7:10,ncol=2)
# [,1] [,2]
# [1,]    7    9
# [2,]    8   10

# DESIRE:
#  7 36
# 14 45
# 21 54
#  8 40
# 16 50
# 24 60

Esto funciona, pero no es la solución general que estoy buscando:

rr1 <- t(t(ff) * bb[1,])
rr2 <- t(t(ff) * bb[2,])
rbind(rr1,rr2)
# [,1] [,2]
# [1,]    7   36
# [2,]   14   45
# [3,]   21   54
# [4,]    8   40
# [5,]   16   50
# [6,]   24   60

Este siguiente bloque de código parece bastante eficiente y es general. Pero hay una manera mejor? ¿Algo como kronecker(ffa,bba)? (que claramente no funciona en este caso)

ffa <- matrix(rep(t(ff),2), ncol=2, byrow=T)
bba <- matrix(rep(bb,each=3), ncol=2)
ffa * bba
# [,1] [,2]
# [1,]    7   36
# [2,]   14   45
# [3,]   21   54
# [4,]    8   40
# [5,]   16   50
# [6,]   24   60

Esto está relacionado con mis otras preguntas:

  1. Uso de la función de aplicación sobre el margen de la fila con expectativa de resultados apilados, donde intento comprender el comportamiento de apply en sí y:

  2. ¿Es este un ejemplo de algún producto matricial más general? ?, donde pregunto sobre las matemáticas teóricas, específicamente.

1
lowndrul 5 feb. 2019 a las 19:38

2 respuestas

La mejor respuesta

Utilice un producto de kronecker y seleccione las columnas correspondientes:

kronecker(bb, ff)[, c(diag(ncol(bb))) == 1]

O usando el operador infijo para kronecker:

(bb %x% ff)[, c(diag(ncol(bb))) == 1]

Otro enfoque es convertir los argumentos en marcos de datos y mapply kronecker a través de ellos. Para el caso de la pregunta esto realiza el cálculo cbind(bb[, 1] %x% ff[, 1], bb[, 2] %x% ff[, 2]) pero de una manera más general sin recurrir a índices:

mapply(kronecker, as.data.frame(bb), as.data.frame(ff))

O usando el operador infijo para kronecker:

mapply(`%x%`, as.data.frame(bb), as.data.frame(ff))
3
G. Grothendieck 5 feb. 2019 a las 17:50

La funcionalidad que busca está disponible dentro del paquete Matrix como la función KhatriRao. Dado que la función está en Matrix, la salida es una matriz de clase "dgCMatrix" (matriz dispersa). Puede transformarlo en una matriz ordinaria de clase "matriz" mediante as.matrix.

library(Matrix)
as.matrix(KhatriRao(bb, ff))
3
Øyvind Langsrud 6 feb. 2019 a las 09:18