Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Ciao, sono un principiante nella scrittura di script in qualsiasi linguaggio. Al momento sto procedendo con quello che pensavo sarebbe stato un semplice compito pratico. Sto usando JMP18. Il mio obiettivo è automatizzare un'operazione di routine che faccio con dataset in crescita nel tempo. L'operazione di routine consiste innanzitutto nel determinare la scala temporale e poi mostrare la variazione dei dati su quella scala temporale per dataset di grandi dimensioni. Il modo di base in cui mi sto avvicinando a questo è creare nuove colonne per riempire tutti i dati iniziali e usare formule su più colonne per ottenere le differenze. Se qualcuno ha un suggerimento migliore, lo apprezzerei. Ecco dove mi trovo:
In sostanza, ho un set di dati e voglio ottenere quanto segue.
1) Voglio prendere le colonne data e ora, unirle in una singola colonna, quindi trovare il minimo e usarlo per creare una data di inizio. Posso quindi sottrarre gli orari per vedere la differenza di tempo tra i dati. Tutto questo era abbastanza semplice con le funzioni formula(). Tutto qui funziona alla grande.
2) Voglio fare qualcosa di simile a diverse colonne di dati, ma non riesco a fare quello che ho fatto prima per trovare il valore iniziale. I dati iniziali sono determinati dal tempo minimo trovato in quello che ho fatto prima per ogni elemento univoco in una terza colonna (chiamata Unique_Fruit nel codice sottostante). Per il bene di questo forum, per ogni unique_fruit, voglio creare una colonna che contenga i valori iniziali dei dati per quel frutto in modo da poter calcolare rapidamente le modifiche dalla colonna di dati effettiva.
Il mio attuale script JSL è qui sotto. Ho una formula di codice fittizio in cui non ho capito cosa fare. Sono i passaggi in cui ho usato la funzione If, ho trovato che i tempi erano uguali tra loro e ho impostato il valore solo per quelle celle. Il mio pensiero originale era di provare a usare un ciclo for e iterare nella formula, ma non sembrava funzionare.
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>Automazione e scripting</LINGO-LABEL></LINGO-LABS><LINGO-SUB id="lingo-sub-844929" slang="en-US" mode="CREATE">Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?</LINGO-SUB><LINGO-BODY id="lingo-body-844929" slang="en-US" mode="CREATE"><P>Puoi fornire un esempio di dataset + colonna con risposta corretta? Molto probabilmente puoi ottenere i valori iniziali usando qualcosa del genere, ma devi modificare il confronto poiché questo ottiene il primo valore per ogni categoria</P>
<BR />
<PRE><CODE class=" language-jsl">Col Cumulative Sum(If(Row() == Col Min(Row(), :age), :height, .), :age)
dove :age è unique_fruit e :height è la colonna del valore. Puoi anche utilizzare Lag() e variabili.
Ci sono anche alcune modifiche che apporterei al tuo script per renderlo un po' più robusto.
- Avvia lo script con Nomi predefiniti qui(1);
- Poiché hai riferimento a una tabella dati, usala
- DataTable << Nuova colonna(...
- Valuterei anche di cambiare DataTable in dt o qualcosa di simile poiché JMP ha una funzione chiamata Datatable()
- Quando si esegue un ciclo su una tabella dati, utilizzare For Each Row anziché For poiché è il suo caso d'uso speciale
- Se desideri avere nuove colonne nella tabella JMP senza formule, hai poche opzioni:
- Usa la combinazione Nuova colonna + Formula + Esegui formule + Elimina formula
- Crea una nuova colonna e fai un ciclo sulla tabella dati (come stai facendo)
- Poi c'è un metodo un po' pignolo di usare << Applica formula ma io mi limiterei a usare prima quelli (di solito uso il primo)
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Benvenuti nella Community.
Sono d'accordo con Jarmo, una tabella di dati di esempio.
Ti suggerisco anche di fornire un esempio concreto di quelli che sono i risultati attesi.
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Grazie per il suggerimento. Sto tentando un set di dati fittizio e quello che faccio attualmente manualmente. Per impostare i valori iniziali, guardo ogni elemento univoco e chiamo i dati da quella cella e popola l'intera colonna in modo da poter passare alla parte successiva del calcolo. Proverò ad aggiornare anche il resto dello script con i tuoi suggerimenti, ma il problema principale non è ancora risolto, credo per me (o non ho ancora capito).
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Ciao @bubbo , dai un'occhiata a https://marketplace.jmp.com/appdetails/Normalization+GUI
Facilita il compito di normalizzare i dati tramite un valore iniziale (sottrazione o divisione) per gruppo.
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Non è stato risolto perché in genere ci vuole più tempo per creare dati di mockup che per rispondere alla domanda corretta . Dovresti essere in grado di utilizzare qualcosa di simile per i valori iniziali
Col Min(If(:Date Number Format == Col Min(:Date Number Format, :Unique_Fruit), :Key_Taste, .), :Unique_Fruit)
Questo non è l'unico modo per costruirli, ma qualcosa del genere funziona abbastanza spesso
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Grazie mille. Solo per chiarire, non stavo cercando di dare la colpa alla tua prima risposta, più che altro stavo cercando di implementarla in alcune iterazioni e pensavo che mi mancasse ancora qualcosa. Avrei dovuto continuare perché probabilmente sarei finito con la risposta che hai mostrato qui (alla fine), ma come ho detto prima sono nuovo nello scripting di queste cose, quindi è lento.
Per curiosità, perché c'è il "." in else?
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Il valore mancante è lì per tentare di "costringere" il Col Min ad avere una sola opzione tra cui scegliere, poiché ignorerà i valori mancanti.
È possibile suddividere questo tipo di formule in più parti nel tentativo di comprenderle meglio (a volte possono comunque risultare molto criptiche)
//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: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?In futuro, compiti come questo diventeranno super facili:
https://community.jmp.com/t5/JMP-Wish-List/Group-by-sooo-useful-how-about-Interpolate/idc-p/828679/highlight/true#M6896
Insieme a Col Interpolate, molte nuove funzioni (e funzionalità) saranno aggiunte alle aggregazioni Col:)
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Ehi, mi è venuto in mente un altro pensiero mentre ci giocavo. Se volessi fare qualcosa di più vicino a quello che pensavo di dover fare quando ho pubblicato questo, come si fa? Dove mi trovo è scrivere una variabile che memorizza un elenco e poi provare a far scorrere il codice attraverso quell'elenco per popolare la formula. Invece di popolare la variabile rimane all'interno della formula anziché aggiornarsi a uno dei valori dell'elenco. È qualcosa che può essere fatto all'interno della funzione formula?
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Grazie per la spiegazione qui. Ci sto giocando un po' mentre continuo questo piccolo progetto per me stesso e vedo dove posso portarlo.
Re: Principiante che prova a scrivere uno script / Come eseguire l'iterazione all'interno della funzione formula?Puoi ottenere un elenco di valori/raccogliere un elenco di valori all'interno di una formula, ma devi solo stare attento a come aggiorni i valori (usare As Constant o If(Row() == 1,...) può aiutare). Inoltre potresti voler evitare i loop all'interno delle formule, poiché si attivano piuttosto spesso.
Potresti usare Lag() ma questo richiederebbe che i tuoi dati siano ordinati (può essere fatto senza ordinamento, ma può complicarsi rapidamente), ma di solito l'idea è qualcosa del genere
If(Row() == 1,
init_taste = :Key_Taste
);
If(:Unique_Fruit != Lag(:Unique_Fruit),
init_taste = :Key_Taste;
);
init_taste;
Da notare che ho ordinato i dati in base al formato numero data e a Unique_Fruit.