Comment utiliser JSL pour classer et résumer les données au milieu de la branche matricielle, et obtenir les résultats récapitulatifs sous forme de matrice?

Merci les experts!
dt=Open("$SAMPLE_DATA/Big Class.jmp");
ar=dt<<GETASMATRIX></GETASMATRIX>
Je ne suis pas sûr que ce soit la meilleure façon d'obtenir votre résultat final, mais si vous vouliez le faire en utilisant uniquement des matrices, vous pouvez:
NamesDefaultToHere(1);
// Sample data
dt = Open("$SAMPLE_DATA/Big Class.jmp");
// Matrix with all 'height' and 'weight' values
ar = dt << GetAsMatrix({4,5});
// Discard rows
ar = ar[6::35, 0];
// Find out the distinct levels of 'height'
hl = Matrix(AssociativeArray(ar[0,1]) << getKeys);
// Build the average 'weight' for each level into a new matrix 'rm'
rm = J(NRow(hl), 2, .);
for(h=1, h<=NRow(hl), h++,
rm[h, 1] = hl[h];
rm[h, 2] = VMean(ar[Loc(ar[0, 1] == hl[h]), 2]);
);
Print(rm);Merci ian! C'est ainsi que fonctionne ce cycle.
ar=dt<<GETASMATRIX></GETASMATRIX>
Voici une approche qui évite les boucles, bien qu'elle crée des tables invisibles. Si les performances sont adaptées à vos besoins, cette approche est simple à utiliser et à comprendre.
Acclamations,
Brady
dt = open("$Sample_Data/Big Class.jmp");
dtSub = dt << subset(rows(6::35), invisible);
dtsum = dtsub << summary(group(:height), mean(weight), invisible);
mat = dtSum << get as Matrix;
close(dtSum, nosave);
close(dtSub, nosave);
show(mat);ÉDITER:
J'ai remarqué une faute de frappe dans la version originale du code ci-dessous, que j'ai corrigée. Dans la dernière ligne, la faute de frappe était :
maintenant(s)
À la place, utilisez :
maintenant (h)
Bien sûr, nrow (n) ou nrow(m) fonctionnerait également puisque chacun des vecteurs h, n et m ont le même nombre de lignes.
Désolé pour ça.
Acclamations,
Brady
//////////////////////////// Message original :
En examinant les performances de l'approche basée sur la table, elle est beaucoup plus lente que les approches basées sur la matrice, ce qui pourrait compenser sa simplicité, selon votre table.
Voici une autre approche matricielle ; bien qu'il fonctionne de manière similaire à celui publié par Ian, je l'inclus pour plusieurs raisons : a) pour introduire l'idée d'une colonne "sélectionnée", qui signale 1 si une ligne est sélectionnée et 0 sinon, b) pour afficher un "piratage" " de la fonction récapitulative et c) car cela évite le bouclage et les éventuels pièges d'indexation qui y sont associés.
Premièrement : la colonne "Sélectionné". Dans la première ligne du code ci-dessous, nous ajoutons une nouvelle colonne au tableau, qui se met à 1 dans les lignes sélectionnées et à 0 ailleurs. Cela nous permet de créer une colonne de regroupement supplémentaire, dans le but d'utiliser des plates-formes et des fonctions basées sur des tableaux, telles que Résumé et Résumé, sans avoir à créer de nouveaux tableaux.
Ensuite, le hack Summarize() : notez que nous regroupons par :selected et :height. Alors que les valeurs h, n et m sont renvoyées dans des matrices, les valeurs par variable(s) sont placées dans des listes de chaînes... même si elles POURRAIENT être placées dans des matrices. Donc dans ce cas, b est une liste de deux listes de chaînes. Ainsi, si nous voulons l'une de ces valeurs sous forme de matrice, nous pouvons soit convertir la liste de chaînes souhaitée en une matrice (ce qui est coûteux si la liste est grande) ou nous pouvons calculer une statistique "bon marché", comme Min ou Max, sur la même colonne, pour obtenir ces valeurs... ce que nous faisons ci-dessous pour la colonne de hauteur.
Acclamations,
Brady
dt << New Column( "Selected", formula( Selected( Row State() ) ) );
dt << Select Rows( 6 :: 35 );
Summarize( dt, b = by( :Selected, :height ), h = max( :height), n = Count( :weight ), m = Mean( :weight ) );
sumMat = (h || n || m)[contains(b[1], "1"):: nrow(h),0]; //only use the results where selected == 1