Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Bonjour, je suis débutant en écriture de script dans n'importe quelle langue. Je suis actuellement en train de parcourir ce que je pensais être une tâche pratique simple. J'utilise JMP18. Mon objectif est d'automatiser une opération de routine que j'effectue avec des ensembles de données croissants au fil du temps. L'opération de routine consiste d'abord à déterminer l'échelle de temps, puis à afficher l'évolution des données sur cette échelle de temps pour les grands ensembles de données. La manière de base dont j'aborde cela consiste à créer de nouvelles colonnes pour remplir toutes les données initiales et à utiliser des formules sur plus de colonnes pour obtenir les différences. Si quelqu'un a une meilleure suggestion, je l'apprécierais. Voici où j'en suis :
Essentiellement, j’ai un ensemble de données et je souhaite atteindre l’objectif suivant.
1) Je cherche à prendre les colonnes de date et d'heure, à les rassembler en une seule colonne, puis à trouver le minimum et à l'utiliser pour créer une date de début. Je peux ensuite soustraire les heures pour voir la différence de temps entre les données. Tout cela était assez simple avec les fonctions formula(). Tout fonctionne parfaitement ici.
2) Je souhaite faire quelque chose de similaire à plusieurs colonnes de données, mais je ne peux pas faire ce que j'ai fait avant pour trouver la valeur initiale. Les données initiales sont déterminées par le temps minimum trouvé dans ce que j'ai fait avant pour chaque élément unique dans une troisième colonne (appelée Unique_Fruit dans le code ci-dessous). Pour les besoins de ce forum, pour chaque unique_fruit, je souhaite créer une colonne contenant les valeurs initiales des données pour ce fruit afin de pouvoir ensuite calculer rapidement les changements à partir de la colonne de données réelle.
Mon script JSL actuel est ci-dessous. J'ai une formule de code factice où je n'ai pas compris quoi faire. Ce sont les étapes où j'ai utilisé la fonction If, trouvé que les temps sont égaux et défini la valeur uniquement pour ces cellules. Mon idée initiale était d'essayer d'utiliser une boucle for et d'itérer dans la formule, mais cela ne semble pas fonctionner.
DataTable = Current Data Table();
New Column( "Date Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Date Number Format[i] = Num( DataTable:Key_Date[i] );
);
New Column( "Time Number Format", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Time Number Format[i] = Num( DataTable:Key_Time[i] );
);
New Column( "Current_Time", Numeric, "Continuous" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Current_Time[i] = DataTable:Date Number Format[i] + DataTable:Time Number Format[i];
);
New Column( "Unique_Fruit", Character, "Nominal" );
For( i = 1, i <= N Rows( DataTable ), i++,
DataTable:Unique_Fruit[i] = DataTable:Fruit[i] || "-" || DataTable:Type[i];
);
New Column( "Starting_Date_Number_Format", Numeric, "Continuous",
Formula( Col Minimum( :Current_Time, :Unique_Fruit ) )
);
New Column( "Minutes", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Minute", "fractional" ) )
);
New Column( "Days", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Day", "fractional" ) )
);
New Column( "Weeks", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Week", "fractional" ) )
);
New Column( "Months", Numeric, "Continuous",
Formula( Date Difference( :Starting_Date_Number_Format, :Current_Time, "Month", "fractional" ) )
);
New Column( "Initial_Taste", Numeric, "Continuous",
Formula(
If( :Current_Time == :Starting_Date_Number_Format, :Key_Taste, . )
)
);
For( i = 1, i <= N Rows( DataTable ), i++,
If( DataTable:Current_Time[i] == DataTable:Starting_Date_Number_Format[i],
DataTable:Initial_Taste[i] = DataTable:Key_Taste[i];
);
);
New Column( "Delta_Taste", Numeric, "Continuous",
Formula( :Key_Taste - :Initial_Taste )
);
New Column( "%_Change_Taste", Numeric, "Continuous",
Formula( ( :Delta_Taste / :Initial_Taste ) * 100 + 100 )
);</CODE></P><BR /></LINGO-BODY><LINGO-LABS id="lingo-labs-844919" slang="en-US" mode="CREATE"><LINGO-LABEL>Automatisation et scripts</LINGO-LABEL></LINGO-LABS><LINGO-SUB id="lingo-sub-844929" slang="en-US" mode="CREATE">Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?</LINGO-SUB><LINGO-BODY id="lingo-body-844929" slang="en-US" mode="CREATE"><P>Pouvez-vous fournir un exemple d'ensemble de données + colonne avec la réponse correcte ? Vous pouvez très probablement obtenir les valeurs initiales en utilisant quelque chose comme ceci, mais vous devez modifier la comparaison car celle-ci obtient la première valeur pour chaque catégorie</P>
<BR />
<PRE><CODE class=" language-jsl">Col Cumulative Sum(If(Row() == Col Min(Row(), :age), :height, .), :age)
où :age est unique_fruit et :height est votre colonne de valeur. Vous pouvez également utiliser Lag() et les variables.
Il y a également quelques modifications que j'apporterais à votre script pour le rendre un peu plus robuste.
- Démarrez votre script avec les noms par défaut ici (1) ;
- Comme vous avez fait référence à une table de données, utilisez-la
- DataTable << Nouvelle colonne(...
- J'envisagerais également de remplacer DataTable par dt ou quelque chose de similaire, car JMP possède une fonction appelée Datatable()
- Lors d'une boucle sur une table de données, utilisez For Each Row au lieu de For car c'est son cas d'utilisation spécial
- Lorsque vous souhaitez avoir de nouvelles colonnes dans la table JMP sans avoir de formules, vous avez peu d'options :
- Utiliser la combinaison Nouvelle colonne + Formule + Exécuter les formules + Supprimer la formule
- Créez une nouvelle colonne et parcourez la table de données (comme vous le faites)
- Ensuite, il existe une méthode un peu capricieuse qui consiste à utiliser << Appliquer la formule, mais je m'en tiendrais à celle-là en premier (généralement, j'utilise la première)
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Bienvenue dans la communauté.
Je suis d'accord avec Jarmo, un exemple de tableau de données.
Je vous suggère également de fournir un exemple concret de ce que vous attendez des résultats.
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Merci pour la suggestion. J'essaie de créer un jeu de données fictif et ce que je fais actuellement manuellement. Pour définir les valeurs initiales, je regarde chaque élément unique et j'appelle les données de cette cellule et je remplis toute la colonne afin de pouvoir ensuite passer à la partie suivante du calcul. Je vais essayer de mettre à jour le reste du script avec vos suggestions également, mais le problème principal n'est pas encore résolu, je pense, pour moi (ou je n'ai pas encore compris).
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Bonjour @bub , veuillez consulter https://marketplace.jmp.com/appdetails/Normalization+GUI
Il facilite la tâche de normalisation des données par une valeur initiale (soustraire ou diviser) - par groupe.
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Ce problème n'a pas été résolu car il faut généralement plus de temps pour créer des données de maquette que pour répondre à la bonne question. Vous devriez pouvoir utiliser quelque chose comme ceci pour les valeurs initiales
Col Min(If(:Date Number Format == Col Min(:Date Number Format, :Unique_Fruit), :Key_Taste, .), :Unique_Fruit)
Ce n'est pas la seule façon de les construire, mais quelque chose comme ça fonctionne assez souvent
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Merci beaucoup. Juste pour clarifier, je n'essayais pas de rejeter la faute sur votre première réponse, mais plutôt que j'essayais de l'implémenter sur quelques itérations et que je pensais qu'il me manquait encore quelque chose. J'aurais dû continuer car j'aurais probablement fini par arriver à la réponse que vous avez montrée ici (éventuellement), mais comme je l'ai dit plus tôt, je suis nouveau dans la création de scripts pour ces choses, donc ça avance lentement.
Par curiosité, pourquoi avoir le « . » dans le « else » ?
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?La valeur manquante est là pour tenter de « forcer » le Col Min à n'avoir qu'une seule option parmi laquelle choisir, car elle ignorera les valeurs manquantes.
Vous pouvez diviser ce type de formules en plusieurs parties pour tenter de mieux les comprendre (parfois, elles peuvent encore être très cryptiques)
//col1
Col Min(:Date Number Format, :Unique_Fruit)
//col2
:Date Number Format == :col1
//col3
If(:col2, :Key_Taste, .)
//col4
Col Min(:col3, :Unique_Fruit)

Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?À l’avenir, des tâches comme celle-ci deviendront très faciles :
https://community.jmp.com/t5/JMP-Wish-List/Group-by-sooo-useful-how-about-Interpolate/idc-p/828679/highlight/true#M6896
Avec Col Interpolate, de nombreuses nouvelles fonctions (et fonctionnalités) seront ajoutées aux agrégations Col:)
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Hé, j'ai eu une autre idée en jouant avec ça. Si je voulais faire quelque chose de plus proche de ce que je pensais devoir faire à l'origine lorsque j'ai posté ceci, comment cela se fait-il ? Là où j'en suis, c'est d'écrire une variable qui stocke une liste, puis d'essayer de faire en sorte que le code parcoure cette liste pour remplir la formule. Au lieu de remplir la variable, elle reste à l'intérieur de la formule plutôt que de mettre à jour l'une des valeurs de la liste. Est-ce quelque chose qui peut être fait dans la fonction de formule ?
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Merci pour l'explication ici. Je joue avec tout ça pendant que je continue ce petit projet pour moi-même et que je vois où je peux le mener.
Re : Débutant essayant d'écrire un script / Comment itérer dans la fonction de formule ?Vous pouvez obtenir une liste de valeurs/collecter une liste de valeurs à l'intérieur d'une formule, mais vous devez faire attention à la façon dont vous mettez à jour les valeurs (l'utilisation de As Constant ou If(Row() == 1,...) peut aider). Vous pouvez également éviter les boucles à l'intérieur des formules, car elles se déclenchent assez souvent.
Vous pouvez utiliser Lag() mais cela nécessiterait que vos données soient triées (cela peut être fait sans tri, mais cela peut rapidement devenir compliqué), mais généralement l'idée est quelque chose comme ça
If(Row() == 1,
init_taste = :Key_Taste
);
If(:Unique_Fruit != Lag(:Unique_Fruit),
init_taste = :Key_Taste;
);
init_taste;
Notez que j'ai trié les données par format de numéro de date et fruit unique.