MMULT no es conmutativa: la misma agregación funciona en horizontal y falla en vertical
Esta vez la duda llegó con prisa y todo: Juan quería dejarla resuelta "antes de que Francia nos mande para casa". Tenía dos bases de datos con importes por persona y necesitaba consolidarlas sumando por nombre único, sin tabla dinámica y sin columnas auxiliares, apoyándose en una multiplicación matricial con MMULT.
Con los datos en horizontal le funcionaba. Apilaba importes y nombres, sacaba los nombres únicos, construía una matriz de comparación de ceros y unos, y multiplicaba:
``
=APILARH(B7:C7;G7:I7)
=APILARH(B6:C6;G6:I6)
=UNICOS(A13#;1)
=BYCOL(A13#&"|";CONCAT)
=N(ENCOL(A18#)=A19#)
=MMULT(A11#;A21#)
`
La última línea multiplica una matriz de 1x5 (los importes) por otra de 5x3 (la comparación) y devuelve 1x3: los totales por nombre único. Perfecto.
El problema aparecía al replicar exactamente lo mismo en vertical. Mismos pasos, misma lógica, y el resultado era un error. Juan lo resumía así: "tengo una duda que no me deja vivir; sigo los pasos, pero no entiendo cuál es el motivo".
La primera pista de la comunidad fue el requisito de dimensiones: el número de columnas de la primera matriz debe coincidir con el número de filas de la segunda. Dicho de otra forma, no es lo mismo 5 columnas por 5 filas que 3 columnas por 1 fila. Nacho añadió la pieza que explicaba también por qué en el caso horizontal invertir los argumentos daba error: MMULT no es una operación conmutativa, el orden sí afecta al resultado.
Ahí estaba el fallo. En vertical, la matriz de comparación nacía de 5 filas por 3 columnas:
`
=ENFILA(K17#&"|")
=N(ENCOL(K27#)=K28#)
`
Y al multiplicarla por el vector de importes de 5x1, las dimensiones no encajaban por ningún lado:
`
=MMULT(N17#;K30#)
`
Leo devolvió el libro con dos salidas distintas, que es lo interesante del caso.
La primera, transponer la matriz de comparación justo antes de multiplicar, para convertir ese 5x3 en un 3x5 que sí case con el vector 5x1:
`
=MMULT(TRANSPONER(K30#);N17#)
`
La segunda, más limpia, consiste en no generar nunca la matriz girada: basta con invertir el sentido de la comparación desde el principio, de forma que la matriz ya nazca 3x5 y no haga falta transponer nada después.
`
=N(K27#=ENCOL(K28#))
=MMULT(O30#;N17#)
`
Las dos devuelven lo mismo (200 y 100), y en ambos casos se acaba multiplicando una matriz de 3x5 por una de 5x1 para obtener una de 3x1.
La regla que Leo dejó escrita en el propio fichero, y que conviene tener a mano cada vez que aparece MMULT: para multiplicar M1 por M2, el número de filas de M2 debe ser igual al número de columnas de M1, y el resultado tendrá las filas de M1 y las columnas de M2.
La moraleja práctica es que pasar una construcción matricial de horizontal a vertical no es traducir APILARH por APILARV y ya está. Al cambiar la orientación, la matriz de comparación cambia de forma, y con ella el orden en que hay que pasar los argumentos a MMULT`.
Juan lo cerró al día siguiente con un "espectacular. Gracias. Mil."
El ZIP incluye los dos libros: el planteamiento original con el caso que funcionaba y el que no, y el fichero de Leo con las dos soluciones y el esquema de dimensiones.
Cuando la misma fórmula funciona en horizontal y falla en vertical
Hay un tipo de error especialmente frustrante en Excel: el que aparece cuando has hecho algo bien, lo repites con los datos girados y de pronto deja de funcionar. No has cambiado la lógica, no has cambiado las funciones, solo la orientación. Y sin embargo, error.
Eso es exactamente lo que le pasó a un miembro de la comunidad al consolidar dos bases de datos con MMULT. Su caso ilustra algo que se olvida a menudo: la multiplicación matricial tiene reglas de dimensiones estrictas, y el orden de los argumentos no es intercambiable.
El problema
La situación de partida era sencilla de describir. Dos bases de datos con importes asignados a personas, con nombres repetidos entre ambas, y la necesidad de obtener el total por nombre único. Sin tabla dinámica y sin columnas auxiliares.
Con los datos dispuestos en horizontal, la construcción funcionaba a la primera. El proceso tenía cuatro pasos:
Apilar los importes de las dos tablas en una sola fila y hacer lo mismo con los nombres.
`` =APILARH(B7:C7;G7:I7) =APILARH(B6:C6;G6:I6) ``
Extraer los nombres únicos, indicando con el segundo argumento que la comparación se hace por columnas.
`` =UNICOS(A13#;1) ``
Construir una matriz de ceros y unos que marque, para cada nombre de la lista completa, a qué nombre único corresponde. La función N convierte los VERDADERO y FALSO en 1 y 0.
`` =N(ENCOL(A18#)=A19#) ``
Y finalmente multiplicar el vector de importes por esa matriz de marcas.
`` =MMULT(A11#;A21#) ``
Aquí se multiplica una matriz de 1 fila por 5 columnas (los importes) por otra de 5 filas por 3 columnas (la comparación). El resultado es de 1 fila por 3 columnas: los totales por nombre único. Impecable.
El problema llegó al montar lo mismo en vertical. Mismos pasos, misma lógica, y como resultado un error que no había manera de justificar.
Solución paso a paso
La primera aportación de la comunidad fue recordar el requisito de dimensiones de la multiplicación matricial: el número de columnas de la primera matriz debe coincidir con el de filas de la segunda. Dicho de forma más gráfica, no es lo mismo 5 columnas por 5 filas que 3 columnas por 1 fila.
A eso se sumó la observación que cerraba el círculo: MMULT no es una operación conmutativa. Cambiar el orden de los argumentos no devuelve el mismo resultado en otra disposición; devuelve otro resultado, o directamente un error.
Con esas dos piezas se veía el fallo. En la versión vertical, la matriz de comparación nacía con 5 filas y 3 columnas:
`` =ENFILA(K17#&"|") =N(ENCOL(K27#)=K28#) ``
Y al intentar multiplicarla por el vector de importes, de 5 filas por 1 columna, las dimensiones no encajaban en ningún orden posible:
`` =MMULT(N17#;K30#) ``
A partir de ahí surgieron dos soluciones distintas, y ahí está lo interesante del caso.
La primera es correctiva: transponer la matriz de comparación justo antes de multiplicar, convirtiendo ese 5x3 en un 3x5 que sí casa con el vector de 5x1.
`` =MMULT(TRANSPONER(K30#);N17#) ``
La segunda es preventiva y bastante más elegante: no generar nunca la matriz girada. Basta con invertir el sentido de la comparación desde el principio, de modo que la matriz ya nazca con la orientación buena y no haga falta transponer nada después.
`` =N(K27#=ENCOL(K28#)) =MMULT(O30#;N17#) ``
Las dos devuelven el mismo resultado. En ambos casos se termina multiplicando una matriz de 3x5 por una de 5x1 para obtener una de 3x1.
Funciones clave
MMULT: multiplica dos matrices. Exige que las columnas de la primera coincidan con las filas de la segunda, y no es conmutativa.TRANSPONER: gira una matriz, convirtiendo filas en columnas. Es la salida rápida cuando las dimensiones no encajan.APILARHyAPILARV: combinan rangos en horizontal o en vertical. Son la puerta de entrada a este tipo de construcciones.ENCOLyENFILA: reorientan una matriz a una sola columna o a una sola fila. Aquí son las que deciden la forma de la matriz de comparación.UNICOS: extrae los valores distintos. Su segundo argumento indica si la comparación se hace por filas o por columnas.N: convierte VERDADERO y FALSO en 1 y 0, que es lo que permite que la comparación sirva como matriz de marcas.
La regla que conviene memorizar, tal y como quedó escrita en el fichero de la solución: para multiplicar M1 por M2, el número de filas de M2 debe ser igual al número de columnas de M1, y el resultado tendrá las filas de M1 y las columnas de M2.
Conclusión
La lección práctica va más allá de MMULT. Pasar una construcción matricial de horizontal a vertical no consiste en cambiar APILARH por APILARV y seguir adelante. Al girar la orientación de los datos, la matriz intermedia cambia de forma, y con ella el orden en que hay que pasar los argumentos.
Cuando una fórmula matricial falla sin motivo aparente, el primer sitio donde mirar no es la sintaxis: es el tamaño de cada matriz que interviene. Contar filas y columnas en voz alta resuelve más errores de los que parece.
Este caso, como el resto de los que se publican aquí, nació de una duda real planteada en el grupo de WhatsApp de la comunidad de Influexcel y se resolvió en unas horas entre varios miembros. No son ejercicios inventados: son los problemas con los que la gente se pelea de verdad en su trabajo.
Más casos con estas funciones
Más contenido de Excel en InflueXcel
- Calcular porcentajes de mora por sucursal con BYROW, BYCOL y MMULT CasoEzequiel Rivera lanza un reto a la comunidad: dada una tabla de importes de mora por sucursal (filas) y tramo de antigüedad (columnas), calc
- Sustituir SUMAR.SI.CONJUNTO lento por MMULT y BYCOL en análisis de inventario CasoUn miembro desde Ecuador tiene un modelo de inventario con SUMAR.SI.CONJUNTO dentro de una fórmula LET con ELEGIRCOLS y FILTRAR. El problema
- Error #CALC con MAP y AGRUPARPOR: solución con REDUCE+APILARV CasoNuevo reto de Excel resuelto por la comunidad: un usuario necesita aplicar AGRUPARPOR de forma iterativa sobre un rango de códigos de cuenta
- Limitación de BYCOL: cómo obtener múltiples valores por columna CasoSurge una duda sobre por qué una fórmula aparentemente simple con BYCOL genera error. El usuario intenta obtener los 5 mayores valores de ca
- Cálculos iterativos con REDUCE y APILARV en Excel CasoLa comunidad aborda un caso sobre cómo trabajar con bucles iterativos en Excel usando funciones modernas. Un miembro necesita realizar cálcu
- Consolidar datos repetidos con REDUCE, APILARV y PIVOTARPOR CasoLa comunidad aborda un caso de consolidación de datos donde hay tareas con encabezados repetidos que necesitan combinarse dinámicamente. El
- Funciones personalizadas en Excel: LET, LAMBDA y recursividad TutorialCómo pasar de una fórmula escrita a mano a una función propia que puedes llamar por su nombre en cualquier libro. Los tres vídeos de esta pá
- Contar los días de contrato temporal por empresa en Excel TutorialLa reforma laboral limita a 90 los días que una empresa puede tener a alguien contratado de forma temporal, y controlarlo a mano es un infie
- Separar texto en letras, números y caracteres especiales: 3 enfoques con REGEX y sin REGEX CasoUn miembro plantea un reto interesante: dado un texto que mezcla letras, números y caracteres especiales (por ejemplo "abc123!@#"), ¿cómo se
- Partir un texto con separadores sobre todo un rango sin ir celda a celda CasoInteresante problema planteado por Juan: tiene una columna de textos donde cada celda guarda varios valores unidos por el carácter |, y quie