Comparar elemento actual con el anterior: limitaciones de SCAN y solución elegante
Un miembro de la comunidad intenta usar SCAN con una "matriz coja" (dos columnas apiladas horizontalmente) para comparar cada elemento con el anterior y contar los cambios. Pero SCAN siempre compara el mismo elemento consigo mismo, no con el anterior.
Nacho explica por qué falla: SCAN solo procesa la primera columna de su array de entrada. Aunque le pases una matriz de dos columnas con APILARH, SCAN ignora la segunda.
La fórmula original que no funcionaba:
``
=LET(
ra_1; A1:A11;
ra_2; A2:A12;
arr; APILARH(ra_1; ra_2);
result; SCAN(1; arr; LAMBDA(a; row;
UNIRCADENAS("-"; VERDADERO; INDICE(row; 0); INDICE(row; 1))
));
ELEGIRCOLS(result; 1)
)
`
Alternativa con MAP (Argentina): para trabajar con dos rangos en paralelo, MAP acepta múltiples arrays como entrada:
`
=MAP(A1:A11; A2:A12; LAMBDA(prev; curr; prev&"-"&curr))
`
La solución definitiva (John): el problema real no era concatenar, sino contar cambios entre elementos consecutivos. Para eso, no hace falta ni MAP ni LAMBDA:
`
=SCAN(1; A1:A11 <> A2:A12; SUMA)
`
A1:A11 <> A2:A12 genera un array booleano (VERDADERO donde hay cambio), y SCAN con SUMA` acumula el conteo. Elegante y sin una sola función LAMBDA.
Comparar cada valor de una columna con el anterior es una de esas tareas que parecen triviales hasta que intentas hacerlas sin columnas auxiliares. Un miembro de la comunidad quería contar cuántas veces cambia el valor a lo largo de una lista, y lo intentó con SCAN pasándole una "matriz coja": dos columnas apiladas, la original y la misma desplazada una fila. El resultado no era el esperado, y la explicación deja una lección muy útil sobre cómo funciona realmente SCAN.
Por qué falla el intento con SCAN
La fórmula de partida era esta:
=LET(
ra_1; A1:A11;
ra_2; A2:A12;
arr; APILARH(ra_1; ra_2);
result; SCAN(1; arr; LAMBDA(a; row;
UNIRCADENAS("-"; VERDADERO; INDICE(row; 0); INDICE(row; 1))
));
ELEGIRCOLS(result; 1)
)La idea era buena: si apilo el rango consigo mismo desplazado, cada fila tiene a la vez el valor actual y el anterior. El problema es que SCAN solo procesa la primera columna del array que le pasas. Aunque montes una matriz de dos columnas con APILARH, la segunda se ignora por completo. Por eso la fórmula acaba comparando cada elemento consigo mismo en vez de con su vecino.
Merece la pena grabárselo: SCAN está pensado para recorrer un vector arrastrando un acumulador, no para recorrer filas de una matriz de varias columnas.
Alternativa con MAP: dos rangos en paralelo
Si de verdad necesitas trabajar con dos rangos a la vez, la función correcta es MAP, que acepta varios arrays de entrada y los recorre en paralelo, posición a posición:
=MAP(A1:A11; A2:A12; LAMBDA(prev; curr; prev&"-"&curr))Aquí prev recibe el elemento del primer rango y curr el del segundo. Como el segundo rango arranca una fila más abajo, cada pareja que llega a la LAMBDA es exactamente "valor anterior y valor actual". Esta es la forma canónica de comparar elementos consecutivos en Excel 365.
La solución definitiva: ni MAP ni LAMBDA
John dio con el planteamiento que resuelve el problema original de raíz. El objetivo nunca fue concatenar textos, sino contar los cambios entre elementos consecutivos. Y para eso no hace falta ninguna función lambda:
=SCAN(1; NO(A1:A11 = A2:A12); SUMA)Lo que ocurre paso a paso:
A1:A11 = A2:A12compara cada elemento con el siguiente y devuelve una matriz de VERDADERO cuando son iguales.NO(...)le da la vuelta: ahora hay un VERDADERO justo en cada posición donde el valor cambia.SCANconSUMAacumula esa matriz de booleanos, así que el resultado es el conteo de cambios acumulado a lo largo de la lista.
Fíjate en el detalle elegante: SUMA se pasa como función, sin envolverla en LAMBDA. Es la llamada eta-lambda, y funciona siempre que la función que quieres aplicar ya acepte los argumentos en el orden correcto. La fórmula queda en una línea y sin una sola declaración de variables.
Cuándo usar cada uno
SCAN: un solo vector, y necesitas arrastrar un estado (acumulados, rellenos, contadores). Recuerda que ignora la segunda columna en adelante.MAP: varios rangos que hay que recorrer a la vez, elemento contra elemento. Es la herramienta natural para "actual contra anterior".- Aritmética booleana directa: cuando lo único que quieres es contar o marcar coincidencias, muchas veces no necesitas ni
MAPniLAMBDA. Una comparación entre dos rangos desplazados ya produce toda la información.
Funciones clave
SCAN: acumula sobre un vector y devuelve todos los resultados intermedios.MAP: aplica unaLAMBDAa varios arrays en paralelo.NO: invierte una matriz de valores lógicos; sirve para expresar "distinto de" sin operadores raros.APILARHyELEGIRCOLS: útiles para montar y recortar matrices, aunque en este caso el problema se resolvió sin ellas.
Conclusión
El caso deja dos aprendizajes que valen para muchísimas fórmulas: primero, que SCAN mira solo la primera columna, y segundo —más importante— que antes de complicar la fórmula conviene volver a la pregunta original. Aquí la duda parecía "cómo concateno el elemento anterior con el actual" y en realidad era "cuántos cambios hay". Con la pregunta bien planteada, la respuesta cabía en una línea.
Estos giros pasan a diario en la comunidad de InflueXcel: alguien trae una fórmula que no funciona y acaba saliendo una versión más corta y más rápida que la original.
Más casos con estas funciones
Más contenido de Excel en InflueXcel
- Media móvil dinámica: 6 enfoques con SCAN, MMULT y MAP CasoUn miembro de la comunidad tiene un rango con ventas mensuales y necesita generar una columna con la media móvil de los últimos 3 meses usan
- Readmisión de pacientes en 48h: Power Query, LAMBDA/MAP y AGRUPARPOR CasoAndrés Rojas plantea un reto real de datos clínicos: a partir de una tabla con más de un millón de registros de urgencias (IdPaciente, Fecha
- 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á
- Del VBA a una sola fórmula: calcular el RFC mexicano con LET, MAP y expresiones regulares CasoHector llega al grupo con un problema que no se ve todos los días: tiene resuelto el cálculo del RFC mexicano, pero lo tiene en VBA, y quier
- 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
- Descomposición de Cholesky con matrices dinámicas: de VBA a LAMBDA+REDUCE CasoJuan Pablo lanza un reto al grupo: tiene una descomposición de Cholesky resuelta con VBA y quiere saber si se puede hacer con matrices dinám
- Estructurar correctamente LAMBDA con LET y parámetros opcionales CasoNuevo reto de Excel resuelto por la comunidad: un miembro está creando una función LAMBDA personalizada para calcular potencia de bombeo (fó
- Filtrar una tabla por una lista de valores: una LAMBDA propia y su inversa TutorialTe pasan una lista de 30 números de albarán y hay que sacar esas filas de una tabla de miles. Con el autofiltro es marcar casillas una a una
- Extraer máximos por clave y calcular tiempo transcurrido: AGRUPARPOR vs fórmulas clásicas CasoInteresante caso doble que arrancó con una necesidad muy concreta: dada una tabla con columnas Clave, Secuencia y Rev, obtener el máximo de
- Cómo dejar una celda realmente vacía en fórmulas SI, BUSCARX y FILTRAR CasoInteresante problema planteado por un miembro de la comunidad: quiere que sus fórmulas devuelvan una celda realmente vacía cuando no hay res