SUMIF: come ottenere la somma condizionale tra le colonne?<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Voglio calcolare la somma di 10 colonne in una nuova colonna, per cui voglio solo sommare i valori positivi. Allo stesso modo, voglio un'altra colonna che riassuma tutti i valori negativi. In Excel userei la funzione SOMMA.SE: =SOMMA.SE(A1:J1;">0")
Come posso fare qualcosa di simile in JMP?
Usando un semplice esempio in Excel (mentre ovviamente il mio set di dati è più grande), questo è ciò a cui miro:
| UN | B | C | D | somma positiva | somma 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 |
Molte grazie per il vostro aiuto!
Yanne
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Oddio, è stupendo!
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Mi piacciono le formule di colonna così semplici e intelligenti come quella nel post di Brady sopra. Ma sì, spesso si adattano terribilmente alle dimensioni del tavolo.
Un'alternativa sarebbe che la formula della colonna ottenga direttamente la riga corrente senza prima ottenere l'intera matrice in ogni riga. La formula che segue è un tentativo in tal senso.
Non è veloce come il codice JSL di Brady o la somma esplicita su colonne di Ian, ma è molto più veloce, e scala meglio (più o meno linearmente con dimensioni del tavolo ), piuttosto che una formula basata su dt< . Per un tavolo 10000x4 ci vogliono circa 0,2 secondi per funzionare sul mio laptop.
L'esempio mostra anche un metodo alternativo per generalizzare la formula usando una variabile locale invece di costruire le formule in modo dinamico, che può essere un sfida . (in questo esempio si presume che le colonne della formula rimangano sempre le ultime colonne).
//Tabella di esempio
dt = Nuova Tavola ( "Somma condizionale tra colonne" , AddRows ( 10000 )) ;
Per ( io = 1 , io <= 4 , io ++,
dt << Nuova Colonna ( "X" , Numerico , Formula ( Normale casuale ( 0 , 1 )))
) ;
dt << elimina colonna ( 1 ) ;
// Aggiungi somme condizionali su tutte le colonne
dt << Nuova Colonna ( "Somma positiva" ,
Numerico ,
Formula (
Locale ({ io = 0 , N = N col ( Tabella dei dati correnti ()) - 1 } ,
Somma ( Ripetere ({ io ++ ; Colonna ( io )[] * ( Colonna ( io )[] > 0 )} , N ))
)
)
) ;
dt << Nuova Colonna ( "Somma negativa" ,
Numerico ,
Formula (
Locale ({ io = 0 , N = N col ( Tabella dei dati correnti ()) - 2 } ,
Somma ( Ripetere ({ io ++ ; Colonna ( io )[] * ( Colonna ( io )[] < 0 )} , N ))
)
)
) ;
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Come ha già detto Brady, se puoi rinunciare all'aspetto "formula" (che ti consente di aggiungere nuove righe e ottenere risultati automaticamente), l'approccio a matrice si ridimensiona molto meglio.
Ma se volessi creare dinamicamente le colonne della formula, sarebbe simile a questo:
NamesDefaultToHere ( 1 ) ;
// Tabella con sei colonne di origine
dt = Nuova Tavola ( "Somma di colonne" ,
Nuova Colonna ( "Colonna 1" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
Nuova Colonna ( "Colonna 2" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
Nuova Colonna ( "Colonna 3" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
Nuova Colonna ( "Colonna 4" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
Nuova Colonna ( "Colonna 5" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
Nuova Colonna ( "Colonna 6" , Numerico , "Continuo" , Formato ( "Dicembre fisso" , 10 , 3 ) , Formula ( Normale casuale ( 0 , 1 ) ) ) ,
AddRows ( 10 )
) ;
// Elenco di colonne (può essere qualsiasi numero di colonne!)
cLista = dt << getColumnNames ;
// Crea l'espressione della formula 'somma negativa'
colContributo = Espr ( colTBD * Se ( colTBD < 0 , 1 , 0 )) ;
formaArg = Espr ( Aggiungere ()) ;
Per ( C = 1 , C <= NArticoli ( cLista ) , C ++,
thisColContribution = NomeEspr ( Sostituire ( NomeEspr ( colContributo ) , Espr ( colTBD ) , EvalExpr ( AsColumn ( cLista [ C ])))) ;
Inserire ( formaArg , thisColContribution ) ;
) ;
nsEspr = Espr ( Formula ( fTBD )) ;
SostituisciInto ( nsEspr , Espr ( fTBD ) , NomeEspr ( formaArg )) ;
// Stampa(nsEspr);
// Crea l'espressione della formula 'somma positiva'
colContributo = Espr ( colTBD * Se ( colTBD >= 0 , 1 , 0 )) ;
formaArg = Espr ( Aggiungere ()) ;
Per ( C = 1 , C <= NArticoli ( cLista ) , C ++,
thisColContribution = NomeEspr ( Sostituire ( NomeEspr ( colContributo ) , Espr ( colTBD ) , EvalExpr ( AsColumn ( cLista [ C ])))) ;
Inserire ( formaArg , thisColContribution ) ;
) ;
psEspr = Espr ( Formula ( fTBD )) ;
SostituisciInto ( psEspr , Espr ( fTBD ) , NomeEspr ( formaArg )) ;
// Stampa(psEspr);
// Aggiungi le due colonne della formula a dt
nsCol = dt << Nuova colonna ( "Somma dei negativi" , Numerico , Continuo , Formato ( "Dicembre fisso" , 10 , 3 )) ;
makeFormula = Espr ( Inviare ( nsCol )) ;
Inserire ( makeFormula , NomeEspr ( nsEspr )) ;
makeFormula ;
psCol = dt << Nuova colonna ( "Somma dei positivi" , Numerico , Continuo , Formato ( "Dicembre fisso" , 10 , 3 )) ;
makeFormula = Espr ( Inviare ( psCol )) ;
Inserire ( makeFormula , NomeEspr (P sEspr )) ;
makeFormula ;
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?I risultati di Brady corrisponderanno a quelli di Ian, ma devi cambiare questa riga: M = ( dt << Ottieni come Matrix )[ 0 , 1 :: 4 ] ;
a questa: M = ( dt << Ottieni come Matrix )[ 0 , 1 :: 3 ] ;
La tabella creata da Ian contiene solo tre colonne, mentre l'esempio di Brady è per 4 colonne.
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Cari Ian e Brady,
Grazie ad entrambi per il vostro gentile e rapido aiuto!!! Ho provato entrambi gli approcci e in qualche modo ho ottenuto due risultati diversi :-(.
Testando manualmente alcuni esempi, ho scoperto che l'approccio di Ian ha dato il risultato corretto, mentre la sceneggiatura di Brady ha restituito somme molto maggiori. Non ho idea del perché e sfortunatamente sono ancora un principiante di JMP, quindi non riesco a capire cosa sia andato storto. Ma poiché l'approccio di Ian sembrava funzionare bene, ho deciso di attenermi a quello (anche se la formula diventa piuttosto lunga per 10 colonne).
Quindi grazie ad entrambi per il vostro aiuto!!!
(e speriamo che se mai ne avrò bisogno per 100 colonne, JMP avrà una funzione SUMIF per allora;) )
Saluti,
Yanne
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Come menziona Ian, questo può diventare ingombrante per molte colonne. Se non hai veramente bisogno di una formula (ad esempio, le colonne di origine non cambieranno) puoi farlo rapidamente per tutte le righe eseguendo il seguente JSL con la tabella di dati desiderata corrente (il codice presuppone che i numeri siano nelle colonne 1-4 , secondo gli indici nella riga 2 del codice... cambia se necessario ma mantienili contigui):
dt = Tabella dei dati correnti () ;
M = ( dt << Ottieni come Matrix )[ 0 , 1 :: 4 ] ;
dt << nuova colonna ( "Somma positiva" , << valori impostati ( vssum ( emulare ( M > 0 , M ) ` ) ` )) ;
dt << nuova colonna ( "Somma negativa" , << valori impostati ( vssum ( emulare ( M < 0 , M ) ` ) ` )) ;
Se hai bisogno di una formula, puoi usare quanto segue (meglio copiarlo/incollarlo nell'editor), che è semplice, ma funzionerà più lentamente man mano che la tua tabella diventa molto grande perché ottieni l'intera matrice per ogni riga. (Cambiare la disuguaglianza per la somma negativa. IL
operator è la moltiplicazione elementwise usata nella funzione emult() sopra.)
dt = Tabella dei dati correnti () ;
M = ( dt << getasmatrix )[ Riga () , Indice ( 1 , 4 )] ;
Somma ( ( M > 0 )
M ) ;
Il compromesso qui è che, nonostante i suoi limiti di prestazioni, man mano che le funzioni vanno, è piuttosto breve, semplice e facile da modificare se aggiungi più colonne. Lo userei solo su tavoli relativamente piccoli, però. Altrimenti, sarebbe meglio usare qualcosa come suggerisce Ian.
Confrontando i due approcci che descrivo per una tabella di 10.000 righe per 4 colonne di numeri casuali:
Approccio script: 0,002713 secondi
Approccio alla formula: 6,050183 secondi
L'approccio dello script richiede solo 3 secondi su una tabella di 10.000.000 righe per 4 colonne. Ho smesso di eseguire l'approccio della formula dopo un'ora solo su una tabella di 1.000.000 di righe. Dipende davvero dal fatto che tu abbia bisogno del pezzo della formula o che tu sia disposto a salvare uno script nella tabella ed eseguirlo solo se necessario. In tal caso, otterrai un notevole vantaggio in termini di prestazioni.
Saluti,
Brady
Ri: SUMIF: come ottenere la somma condizionale tra le colonne?Potresti usare un approccio come quello in questa tabella:
Nuova Tavola ( "Somma di colonne" ,
Aggiungi righe ( 0 ) ,
Nuova Colonna ( "Colonna 1" ,
Numerico ,
"Continuo" ,
Formato ( "Dicembre fisso" , 10 , 3 ) ,
Formula ( CasualeNormale ( 0 , 1 ))
) ,
Nuova Colonna ( "Colonna 2" ,
Numerico ,
"Continuo" ,
Formato ( "Dicembre fisso" , 10 , 3 ) ,
Formula ( CasualeNormale ( 0 , 1 ))
) ,
Nuova Colonna ( "Colonna 3" ,
Numerico ,
"Continuo" ,
Formato ( "Dicembre fisso" , 10 , 3 ) ,
Formula ( CasualeNormale ( 0 , 1 ))
) ,
Nuova Colonna ( "Somma dei positivi" ,
Numerico ,
"Continuo" ,
Formato ( "Dicembre fisso" , 10 , 3 ) ,
Formula (
: Colonna 1 * Se ( : Colonna 1 >= 0 , 1 , 0 ) + : Colonna 2 *
Se ( : Colonna 2 >= 0 , 1 , 0 ) + : Colonna 3 * Se ( : Colonna 3 >= 0 , 1 , 0 )
)
) ,
Nuova Colonna ( "Somma dei negativi" ,
Numerico ,
"Continuo" ,
Formato ( "Dicembre fisso" , 10 , 3 ) ,
Formula (
: Colonna 1 * Se ( : Colonna 1 < 0 , 1 , 0 ) + : Colonna 2 *
Se ( : Colonna 2 < 0 , 1 , 0 ) + : Colonna 3 * Se ( : Colonna 3 < 0 , 1 , 0 )
)
) ,
AddRows ( 10 )
);
Con molte colonne, potrebbe essere più semplice creare le colonne "somma" richieste a livello di codice.
Ri: SOMMA.SE: come ottenere la somma condizionale tra le colonne?Ciao,
Questo è uno script molto utile per il mio compito attuale.
Funziona benissimo per le mie colonne in cui i valori sono "0/0"
dt << Nuova colonna("Somma",Numerico, Formula(
Locale({i = 0, n = N Col(Tabella dati corrente()) - 1},Somma(Ripeti({i++ ; (Colonna(i)[] =="0/0")}, n))) ));
Tuttavia, come modificarlo per le colonne che contengono "some_character" e devo contare quelle colonne?
Ho allegato una tabella dati con l'ultima colonna "Somma" che ha una formula necessaria.
Ho una tabella di big data e vorrei avere uno script per contare le colonne con valori specifici.
Grazie,
vicepresidente