SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Je veux calculer la somme de 10 colonnes dans une nouvelle colonne, où je veux seulement additionner les valeurs positives. De même, je veux une autre colonne additionnant toutes les valeurs négatives. Dans Excel, j'utiliserais la fonction SUMIF : =SUMIF(A1:J1;">0")
Comment puis-je faire quelque chose de similaire dans JMP ?
En utilisant un exemple simple dans Excel (alors que mon jeu de données est évidemment plus grand), voici ce que je vise :
| UN | B | C | D | somme positive | somme négative |
| 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 |
Merci beaucoup pour votre aide!
Yanne
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Bon sang, c'est magnifique !
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?J'aime ces formules de colonne simples et intelligentes comme celle du post de Brady ci-dessus. Mais oui, ils évoluent souvent terriblement avec la taille de la table.
Une alternative serait que la formule de colonne obtienne directement la ligne actuelle sans obtenir d'abord la matrice entière dans chaque ligne. La formule ci-dessous en est une tentative.
Ce n'est pas aussi rapide que le code JSL de Brady ou la somme explicite de Ian sur les colonnes, mais c'est beaucoup plus rapide, et s'adapte mieux (plus ou moins linéairement avec taille de table ), qu'une formule reposant sur dt< . Pour une table 10000x4, il faut environ 0,2 seconde pour s'exécuter sur mon ordinateur portable.
L'exemple montre également une méthode alternative pour généraliser la formule en utilisant une variable locale au lieu de construire les formules dynamiquement, qui peut être un défi . (dans cet exemple, on suppose que les colonnes de formule restent toujours les dernières colonnes).
// Exemple de tableau
dt = Nouveau tableau ( "Somme conditionnelle sur plusieurs colonnes" , Ajouter des lignes ( 10000 )) ;
Pour ( je = 1 , je <= 4 , je ++,
dt << Nouvelle colonne ( "X" , Numérique , Formule ( Aléatoire Normal ( 0 , 1 )))
) ;
dt << supprimer la colonne ( 1 ) ;
// Ajouter des sommes conditionnelles sur toutes les colonnes
dt << Nouvelle colonne ( "Somme positive" ,
Numérique ,
Formule (
Locale ({ je = 0 , n = Col N ( Tableau de données actuel ()) - 1 } ,
Somme ( Répéter ({ je ++ ; Colonne ( je )[] * ( Colonne ( je )[] > 0 )} , n ))
)
)
) ;
dt << Nouvelle colonne ( "Somme négative" ,
Numérique ,
Formule (
Locale ({ je = 0 , n = Col N ( Tableau de données actuel ()) - 2 } ,
Somme ( Répéter ({ je ++ ; Colonne ( je )[] * ( Colonne ( je )[] < 0 )} , n ))
)
)
) ;
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Comme Brady l'a déjà dit, si vous pouvez renoncer à l'aspect "formule" (qui vous permet d'ajouter de nouvelles lignes et d'obtenir automatiquement des résultats), l'approche matricielle évolue beaucoup mieux.
Mais si vous vouliez créer dynamiquement les colonnes de formules, cela ressemblerait à ceci :
NomsDefaultToHere ( 1 ) ;
// Tableau avec six colonnes source
dt = Nouveau tableau ( "Somme des colonnes" ,
Nouvelle colonne ( "Colonne 1" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Nouvelle colonne ( "Colonne 2" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Nouvelle colonne ( "Colonne 3" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Nouvelle colonne ( "Colonne 4" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Nouvelle colonne ( "Colonne 5" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Nouvelle colonne ( "Colonne 6" , Numérique , "Continu" , Format ( "Déc fixe" , dix , 3 ) , Formule ( Aléatoire Normal ( 0 , 1 ) ) ) ,
Ajouter des lignes ( dix )
) ;
// Liste des colonnes (peut être n'importe quel nombre de colonnes !)
cListe = dt << getColumnNames ;
// Construire l'expression de formule 'somme négative'
colContribution = Expr ( colTBD * Si ( colTBD < 0 , 1 , 0 )) ;
formArg = Expr ( Ajouter ()) ;
Pour ( c = 1 , c <= NIéléments ( cListe ) , c ++,
thisColContribution = NomExpr ( Remplaçant ( NomExpr ( colContribution ) , Expr ( colTBD ) , ExprEval ( CommeColonne ( cListe [ c ])))) ;
Insérer dans ( formArg , thisColContribution ) ;
) ;
nsExpr = Expr ( Formule ( fTBD )) ;
RemplacerDans ( nsExpr , Expr ( fTBD ) , NomExpr ( formArg )) ;
// Affiche(nsExpr);
// Construire l'expression de formule 'somme positive'
colContribution = Expr ( colTBD * Si ( colTBD >= 0 , 1 , 0 )) ;
formArg = Expr ( Ajouter ()) ;
Pour ( c = 1 , c <= NIéléments ( cListe ) , c ++,
thisColContribution = NomExpr ( Remplaçant ( NomExpr ( colContribution ) , Expr ( colTBD ) , ExprEval ( CommeColonne ( cListe [ c ])))) ;
Insérer dans ( formArg , thisColContribution ) ;
) ;
psExpr = Expr ( Formule ( fTBD )) ;
RemplacerDans ( psExpr , Expr ( fTBD ) , NomExpr ( formArg )) ;
// Affiche(psExpr);
// Ajoute les deux colonnes de formule à dt
Col ns = dt << NouvelleColonne ( "Somme des négatifs" , Numérique , Continu , Format ( "Déc fixe" , dix , 3 )) ;
faireFormule = Expr ( Envoyer ( Col ns )) ;
Insérer dans ( faireFormule , NomExpr ( nsExpr )) ;
faireFormule ;
psCol = dt << NouvelleColonne ( "Somme des points positifs" , Numérique , Continu , Format ( "Déc fixe" , dix , 3 )) ;
faireFormule = Expr ( Envoyer ( psCol )) ;
Insérer dans ( faireFormule , NomExpr (p sExpr )) ;
faireFormule ;
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Les résultats de Brady correspondront à ceux de Ian, mais vous devez modifier cette ligne : m = ( dt << Obtenir comme matrice )[ 0 , 1 :: 4 ] ;
pour ça: m = ( dt << Obtenir comme matrice )[ 0 , 1 :: 3 ] ;
Le tableau créé par Ian ne contient que trois colonnes, tandis que l'exemple de Brady est pour 4 colonnes.
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Cher Ian et Brady,
Merci à tous les deux pour votre aide aimable et rapide !!! J'ai essayé les deux approches et j'ai obtenu deux résultats différents :-(.
En testant quelques exemples manuellement, j'ai constaté que l'approche de Ian donnait le bon résultat, tandis que le script de Brady renvoyait des sommes bien plus importantes. Je ne sais pas pourquoi et malheureusement, je suis toujours un débutant JMP, je ne peux donc pas comprendre ce qui n'a pas fonctionné. Mais comme l'approche de Ian semblait bien fonctionner, j'ai décidé de m'en tenir à celle-là (même si la formule devient assez longue pour 10 colonnes).
Alors merci à tous les deux pour votre aide!!!
(et espérons que si jamais j'en ai besoin pour 100 colonnes, JMP aura une fonction SUMIF d'ici là
)
Acclamations,
Yanne
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Comme Ian le mentionne, cela peut devenir compliqué pour de nombreuses colonnes. Si vous n'avez pas vraiment besoin d'une formule (c'est-à-dire que les colonnes source ne changeront pas), vous pouvez le faire rapidement pour toutes les lignes en exécutant le JSL suivant avec la table de données souhaitée actuelle (le code suppose que les chiffres sont dans les colonnes 1-4 , selon les indices de la ligne 2 du code ... changez au besoin mais gardez-les contigus):
dt = Tableau de données actuel () ;
m = ( dt << Obtenir comme matrice )[ 0 , 1 :: 4 ] ;
dt << nouvelle colonne ( "Somme positive" , << définir des valeurs ( vsum ( émuler ( m > 0 , m ) ` ) ` )) ;
dt << nouvelle colonne ( "Somme négative" , << définir des valeurs ( vsum ( émuler ( m < 0 , m ) ` ) ` )) ;
Si vous avez besoin d'une formule, vous pouvez utiliser ce qui suit (le mieux est de le copier/coller dans l'éditeur), ce qui est simple, mais s'exécutera plus lentement à mesure que votre tableau grossit car vous obtenez la matrice entière pour chaque ligne. (Modifier l'inégalité pour la somme négative. Le
L'opérateur est la multiplication élément par élément utilisée dans la fonction emult() ci-dessus.)
dt = Tableau de données actuel () ;
m = ( dt << getasmatrix )[ Rangée () , Indice ( 1 , 4 )] ;
Somme ( ( m > 0 )
m ) ;
Le compromis ici est que malgré ses limitations de performances, au fur et à mesure des fonctions, il est assez court, simple et facile à modifier si vous ajoutez plus de colonnes. Je ne l'utiliserais que sur des tables relativement petites, cependant. Sinon, il serait préférable d'utiliser quelque chose comme le suggère Ian.
En comparant les deux approches que je décris pour un tableau de 10 000 lignes sur 4 colonnes de nombres aléatoires :
Approche du script : 0,002713 seconde
Approche de la formule : 6,050183 secondes
L'approche du script ne prend que 3 secondes sur un tableau de 10 000 000 lignes sur 4 colonnes. J'ai arrêté d'exécuter l'approche de formule après une heure sur seulement une table de 1 000 000 lignes. Il s'agit vraiment de savoir si vous avez besoin de la formule ou si vous êtes prêt à enregistrer un script dans la table et à l'exécuter au besoin. Si c'est le cas, vous obtiendrez un gain de performance considérable.
Acclamations,
brady
Re : SUMIF : comment obtenir la somme conditionnelle entre les colonnes ?Vous pouvez utiliser une approche comme celle-ci dans ce tableau :
Nouveau tableau ( "Somme des colonnes" ,
Ajouter des lignes ( 0 ) ,
Nouvelle colonne ( "Colonne 1" ,
Numérique ,
"Continu" ,
Format ( "Déc fixe" , dix , 3 ) ,
Formule ( AléatoireNormal ( 0 , 1 ))
) ,
Nouvelle colonne ( "Colonne 2" ,
Numérique ,
"Continu" ,
Format ( "Déc fixe" , dix , 3 ) ,
Formule ( AléatoireNormal ( 0 , 1 ))
) ,
Nouvelle colonne ( "Colonne 3" ,
Numérique ,
"Continu" ,
Format ( "Déc fixe" , dix , 3 ) ,
Formule ( AléatoireNormal ( 0 , 1 ))
) ,
Nouvelle colonne ( "Somme des points positifs" ,
Numérique ,
"Continu" ,
Format ( "Déc fixe" , dix , 3 ) ,
Formule (
: Colonne 1 * Si ( : Colonne 1 >= 0 , 1 , 0 ) + : Colonne 2 *
Si ( : Colonne 2 >= 0 , 1 , 0 ) + : Colonne 3 * Si ( : Colonne 3 >= 0 , 1 , 0 )
)
) ,
Nouvelle colonne ( "Somme des négatifs" ,
Numérique ,
"Continu" ,
Format ( "Déc fixe" , dix , 3 ) ,
Formule (
: Colonne 1 * Si ( : Colonne 1 < 0 , 1 , 0 ) + : Colonne 2 *
Si ( : Colonne 2 < 0 , 1 , 0 ) + : Colonne 3 * Si ( : Colonne 3 < 0 , 1 , 0 )
)
) ,
Ajouter des lignes ( dix )
);
Avec de nombreuses colonnes, il peut être plus facile de créer les colonnes "sum" requises par programmation.
Re : SUMIF : comment obtenir la somme conditionnelle sur les colonnes ?Bonjour,
C'est un script très utile pour ma tâche actuelle.
Cela fonctionne très bien pour mes colonnes où les valeurs sont "0/0"
dt << Nouvelle colonne("Somme",Numérique, Formule(
Local({i = 0, n = N Col(Tableau de données actuel()) - 1},Somme(Répéter({i++ ; (Colonne(i)[] =="0/0")}, n))) ));
Cependant, comment le modifier pour les colonnes contenant « some_character » et je dois compter ces colonnes ?
J'ai joint un tableau de données avec la dernière colonne "Somme" contenant une formule nécessaire.
J'ai une table Big Data et j'aimerais avoir un script pour compter les colonnes avec des valeurs spécifiques.
Merci,
Vice-président