SUMIF: ¿cómo obtener la suma condicional en las columnas?<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Quiero calcular la suma de 10 columnas en una nueva columna, por lo que solo quiero sumar los valores positivos. Del mismo modo, quiero otra columna que sume todos los valores negativos. En Excel usaría la función SUMAR.SI: =SUMAR.SI(A1:J1;">0")
¿Cómo puedo hacer algo similar en JMP?
Usando un ejemplo simple en Excel (aunque obviamente mi conjunto de datos es más grande), esto es lo que busco:
| A | B | C | D | suma positiva | suma negativa |
| 1,00 | 2,00 | -7,00 | 5,00 | 8,00 | -7,00 |
| 4,00 | 64,00 | 55,90 | 5,20 | 129,10 | 0,00 |
| 86,10 | -34,44 | 5,60 | 7,21 | 98,91 | -34,44 |
| 6,00 | 8,00 | -96,00 | 6,00 | 20,00 | -96,00 |
| 1,00 | -8,00 | 5,00 | 0,64 | 6,64 | -8,00 |
¡Muchas gracias por su ayuda!
Yanne
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?¡Dios mío, eso es precioso!
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Me gustan las fórmulas de columna tan simples e inteligentes como la de la publicación de Brady anterior. Pero sí, a menudo escalan terriblemente con el tamaño de la mesa.
Una alternativa sería que la fórmula de la columna obtenga la fila actual directamente sin obtener primero la matriz completa en cada fila. La siguiente fórmula es un intento de eso.
No es tan rápido como el código JSL de Brady o la suma explícita sobre columnas de Ian, pero es mucho más rápido. y se escala mejor (más o menos linealmente) con tamaño de mesa ), que una fórmula basada en dt< . Para una mesa de 10000x4, se tarda aproximadamente 0,2 segundos en ejecutarse en mi computadora portátil.
El ejemplo también muestra un método alternativo para generalizar la fórmula usando una variable local en lugar de construir las fórmulas dinámicamente, que puede ser un desafío . (en este ejemplo se supone que las columnas de la fórmula siempre siguen siendo las últimas columnas).
//Tabla de ejemplo
dt = Nueva tabla ( "Suma condicional entre columnas" , Agregar filas ( 10000 )) ;
Para ( i = 1 , i <= 4 , i ++,
dt << Nueva columna ( "X" , Numérico , Fórmula ( Aleatorio normal ( 0 , 1 )))
) ;
dt << eliminar columna ( 1 ) ;
// Agregar sumas condicionales en todas las columnas
dt << Nueva columna ( "Suma positiva" ,
Numérico ,
Fórmula (
Local ({ i = 0 , norte = columna N ( Tabla de datos actual ()) - 1 } ,
Suma ( Repetir ({ i ++ ; Columna ( i )[] * ( Columna ( i )[] > 0 )} , norte ))
)
)
) ;
dt << Nueva columna ( "Suma negativa" ,
Numérico ,
Fórmula (
Local ({ i = 0 , norte = columna N ( Tabla de datos actual ()) - 2 } ,
Suma ( Repetir ({ i ++ ; Columna ( i )[] * ( Columna ( i )[] < 0 )} , norte ))
)
)
) ;
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Como ya dijo Brady, si puede prescindir del aspecto de la 'fórmula' (que le permite agregar nuevas filas y obtener resultados automáticamente), el enfoque matricial escala mucho mejor.
Pero si quisiera crear dinámicamente las columnas de fórmula, se vería así:
Nombres predeterminados a aquí ( 1 ) ;
// Tabla con seis columnas fuente
dt = Nueva tabla ( "Suma de columnas" ,
Nueva columna ( "Columna 1" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Nueva columna ( "Columna 2" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Nueva columna ( "Columna 3" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Nueva columna ( "Columna 4" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Nueva columna ( "Columna 5" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Nueva columna ( "Columna 6" , Numérico , "Continuo" , Formato ( "Diciembre fijo" , 10 , 3 ) , Fórmula ( Aleatorio normal ( 0 , 1 ) ) ) ,
Agregar filas ( 10 )
) ;
// Lista de columnas (¡puede ser cualquier número de columnas!)
cLista = dt << getColumnNames ;
// Construir la expresión de la fórmula 'suma negativa'
colContribución = exp. ( colTBD * Si ( colTBD < 0 , 1 , 0 )) ;
formularioArg = exp. ( Agregar ()) ;
Para ( C = 1 , C <= Nartículos ( cLista ) , C ++,
thisColContribution = NombreExpr ( Sustituto ( NombreExpr ( colContribución ) , exp. ( colTBD ) , EvalExpr ( como columna ( cLista [ C ])))) ;
Insertar en ( formularioArg , thisColContribution ) ;
) ;
nsExpr = exp. ( Fórmula ( fTBD )) ;
Sustituir en ( nsExpr , exp. ( fTBD ) , NombreExpr ( formularioArg )) ;
// Imprimir(nsExpr);
// Construir la expresión de la fórmula 'suma positiva'
colContribución = exp. ( colTBD * Si ( colTBD >= 0 , 1 , 0 )) ;
formularioArg = exp. ( Agregar ()) ;
Para ( C = 1 , C <= Nartículos ( cLista ) , C ++,
thisColContribution = NombreExpr ( Sustituto ( NombreExpr ( colContribución ) , exp. ( colTBD ) , EvalExpr ( como columna ( cLista [ C ])))) ;
Insertar en ( formularioArg , thisColContribution ) ;
) ;
psExpr = exp. ( Fórmula ( fTBD )) ;
Sustituir en ( psExpr , exp. ( fTBD ) , NombreExpr ( formularioArg )) ;
// Imprimir(psExpr);
// Agrega las dos columnas de fórmula a dt
nsCol = dt << NuevaColumna ( "Suma de negativos" , Numérico , Continuo , Formato ( "Diciembre fijo" , 10 , 3 )) ;
hacerFórmula = exp. ( Enviar ( nsCol )) ;
Insertar en ( hacerFórmula , NombreExpr ( nsExpr )) ;
hacerFórmula ;
pscol = dt << NuevaColumna ( "Suma de Positivos" , Numérico , Continuo , Formato ( "Diciembre fijo" , 10 , 3 )) ;
hacerFórmula = exp. ( Enviar ( psCol )) ;
Insertar en ( hacerFórmula , NombreExpr (pag sExpr )) ;
hacerFórmula ;
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Los resultados de Brady coincidirán con los de Ian, pero debes cambiar esta línea: metro = ( dt << Obtener como matriz )[ 0 , 1 :: 4 ] ;
a esto: metro = ( dt << Obtener como matriz )[ 0 , 1 :: 3 ] ;
La tabla que crea Ian solo tiene tres columnas, mientras que el ejemplo de Brady es para 4 columnas.
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Estimados Ian y Brady,
¡Gracias por su amable y rápida ayuda! Probé ambos enfoques y de alguna manera obtuve dos resultados diferentes :-(.
Al probar algunos ejemplos manualmente, descubrí que el enfoque de Ian dio el resultado correcto, mientras que el guión de Brady arrojó sumas mucho mayores. No tengo idea de por qué y desafortunadamente todavía soy un principiante de JMP, así que no puedo entender qué salió mal. Pero como el enfoque de Ian parecía funcionar bien, decidí quedarme con ese (aunque la fórmula es bastante larga para 10 columnas).
Así que gracias a ambos por su ayuda!!!
(y esperemos que si alguna vez necesito esto para 100 columnas, JMP tendrá una función SUMIF para entonces;) )
Salud,
Yanne
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Como menciona Ian, esto puede volverse difícil de manejar para muchas columnas. Si realmente no necesita una fórmula (es decir, las columnas de origen no cambiarán), puede hacerlo rápidamente para todas las filas ejecutando el siguiente JSL con la tabla de datos deseada actual (el código asume que los números están en las columnas 1-4 , según los índices en la línea 2 del código... cámbielos según sea necesario pero manténgalos contiguos):
dt = Tabla de datos actual () ;
metro = ( dt << Obtener como matriz )[ 0 , 1 :: 4 ] ;
dt << nueva columna ( "Suma positiva" , << establecer valores ( versussum ( emular ( metro > 0 , metro ) ` ) ` )) ;
dt << nueva columna ( "Suma negativa" , << establecer valores ( versussum ( emular ( metro < 0 , metro ) ` ) ` )) ;
Si necesita una fórmula, puede usar la siguiente (lo mejor es copiarla/pegarla en el editor), que es simple, pero se ejecutará más lentamente a medida que su tabla crece mucho porque obtiene la matriz completa para cada fila. (Cambia la desigualdad por la suma negativa. El
operador es la multiplicación por elementos utilizada en la función emult() anterior).
dt = Tabla de datos actual () ;
metro = ( dt << obtenerasmatrix )[ Fila () , Índice ( 1 , 4 )] ;
Suma ( ( metro > 0 )
metro ) ;
La compensación aquí es que, a pesar de sus limitaciones de rendimiento, las funciones son bastante cortas, simples y fáciles de cambiar si agrega más columnas. Sin embargo, solo lo usaría en mesas relativamente pequeñas. De lo contrario, sería mejor usar algo como lo sugiere Ian.
Comparando los dos enfoques que describo para una tabla de números aleatorios de 10,000 filas por 4 columnas:
Enfoque de secuencia de comandos: 0,002713 segundos
Enfoque de fórmula: 6.050183 segundos
El enfoque de secuencia de comandos solo toma 3 segundos en una tabla de 10,000,000 filas por 4 columnas. Dejé de ejecutar el enfoque de fórmula después de una hora en solo una tabla de 1,000,000 de filas. Realmente se trata de si necesita la pieza de fórmula o si está dispuesto a guardar un script en la tabla y simplemente ejecutarlo según sea necesario. Si es así, obtendrá una ventaja de rendimiento considerable.
Salud,
Brady
Re: SUMIF: ¿cómo obtener la suma condicional entre columnas?Podría usar un enfoque como ese en esta tabla:
Nueva tabla ( "Suma de columnas" ,
Agregar filas ( 0 ) ,
Nueva columna ( "Columna 1" ,
Numérico ,
"Continuo" ,
Formato ( "Diciembre fijo" , 10 , 3 ) ,
Fórmula ( AleatorioNormal ( 0 , 1 ))
) ,
Nueva columna ( "Columna 2" ,
Numérico ,
"Continuo" ,
Formato ( "Diciembre fijo" , 10 , 3 ) ,
Fórmula ( AleatorioNormal ( 0 , 1 ))
) ,
Nueva columna ( "Columna 3" ,
Numérico ,
"Continuo" ,
Formato ( "Diciembre fijo" , 10 , 3 ) ,
Fórmula ( AleatorioNormal ( 0 , 1 ))
) ,
Nueva columna ( "Suma de Positivos" ,
Numérico ,
"Continuo" ,
Formato ( "Diciembre fijo" , 10 , 3 ) ,
Fórmula (
: columna 1 * Si ( : columna 1 >= 0 , 1 , 0 ) + : columna 2 *
Si ( : columna 2 >= 0 , 1 , 0 ) + : columna 3 * Si ( : columna 3 >= 0 , 1 , 0 )
)
) ,
Nueva columna ( "Suma de negativos" ,
Numérico ,
"Continuo" ,
Formato ( "Diciembre fijo" , 10 , 3 ) ,
Fórmula (
: columna 1 * Si ( : columna 1 < 0 , 1 , 0 ) + : columna 2 *
Si ( : columna 2 < 0 , 1 , 0 ) + : columna 3 * Si ( : columna 3 < 0 , 1 , 0 )
)
) ,
Agregar filas ( 10 )
);
Con muchas columnas, puede ser más fácil construir las columnas de 'suma' requeridas mediante programación.
Re: SUMAR.SI: ¿cómo obtener la suma condicional entre columnas?Hola,
Este es un script muy útil para mi tarea actual.
Funciona muy bien para mis columnas donde los valores son "0/0"
dt << Nueva columna("Suma",Numérico, Fórmula(
Local({i = 0, n = N Col(Tabla de datos actuales()) - 1},Suma(Repetir({i++; (Columna(i)[] =="0/0")}, n))) ));
Sin embargo, ¿cómo editarlo para las columnas que contienen "algún_carácter" y necesito contar esas columnas?
Adjunté una tabla de datos con la última columna "Suma" que tiene una fórmula necesaria.
Tengo una tabla de big data y me gustaría tener un script para contar columnas con valores específicos.
Gracias,
vicepresidente