UN domanda da aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa sulle formule delle colonne ha iniziato questo post. Se utilizzi solo l'editor di formule per creare formule di colonna, puoi ignorare quasi tutto questo. Questo post riguarda l'utilizzo di JSL per creare una formula di colonna.
Innanzitutto, un po' sul comando Formula. Eccone uno davvero semplice:
The formula for column C adds columns A and BLa formula per la colonna C aggiunge le colonne A e B
Lo script della tabella (triangolo in alto a sinistra->copia script della tabella, incolla in un editor) si presenta così:
New Table( "abc", Add Rows( 2 ),
New Column( "a", Numeric, "Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( :a + :p</img> )
)
)
La riga 5 imposta la formula; la formula è un'espressione che aggiunge le colonne aeb. L'espressione non viene eseguita molto più tardi. L'espressione viene salvata, come espressione, come parte della colonna. Se viene aggiunta un'altra riga alla tabella o se i valori nelle colonne aob vengono modificati, l'espressione può essere valutata nuovamente per ottenere un valore per la colonna c.
Questo è un comportamento amichevole e insolito. Insolito perché la maggior parte delle funzioni valuta i propri argomenti: sqrt( 4 + 5 ) restituisce 3. Amichevole perché non vorresti quasi mai che JMP valuti la formula di una colonna prima che fosse assegnata alla colonna.
A volte un'espressione di formula potrebbe essere davvero complicata. Così complicato sarebbe più facile scrivere un programma per scrivere l'espressione. Per farlo nel comando formula, avresti bisogno di un modo per dire al comando formula di prevalutare l'argomento e utilizzare l'espressione risultante come formula. Lo fai aggiungendo un wrapper eval() attorno al codice da pre-valutare. Quando il comando formula vede "eval" avvolto attorno all'espressione, esegue il codice e usa il risultato.
lookup = function({t,u}, expr(a+b) );
New Table( "abc",
Add Rows( 2 ),
New Column( "a",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( eval( lookup(1,2) ) )
)
)
La funzione di "ricerca" definita dall'utente (riga 1) non è molto brillante, ma deve essere eseguita per recuperare expr(a+b) come valore restituito. Alla riga 7, il wrapper eval() significa che la formula della colonna non sarà impostata su "lookup(1,2)", ma sarà invece impostata sull'espressione restituita da lookup(1,2).Stessa tabella di prima, con la stessa formula di colonna.
E se volessi impostare la formula della colonna su un'espressione che inizia con eval() ?In che modo il comando formula può farlo, dal momento che iniziare con eval() significa valutare l'argomento e utilizzare il risultato? (Sarei stato difficile trovare un esempio interessante, ma SM ne ha uno nella risposta della domanda.) La risposta è Nome Espr( ). Name Expr è una funzione JSL che viene normalmente utilizzata per ottenere un'espressione da una variabile JSL senza valutarla. Essendo il wrapper più esterno in un comando di formula, restituisce semplicemente l'argomento senza valutarlo. Il primo esempio potrebbe usarlo, senza una buona ragione tranne questa spiegazione, come questa, per restituire esattamente la stessa tabella:
New Table( "abc", Add Rows( 2 ),
New Column( "a", Numeric, "Continuous",Format( "Best", 12 ),Set Values( [1, 7] )),
New Column( "b",Numeric,"Continuous",Format( "Best", 12 ),Set Values( [2, 9] )),
New Column( "c", Numeric, "Continuous", Format( "Best", 12 ),
Formula( Name Expr( :a + :p</img> ) )
)
)
Ma per SM ad esempio, è necessario a causa dell'uso intelligente di eval (che probabilmente vuole un altro post sul blog per spiegare cosa fa). Ecco il tavolo finale dalla domanda originale. Ho aggiunto la mia idea come seconda colonna di formula.
New Table( "final?",Add Rows( 9 ),
New Column( "color",Character,"Nominal",
Set Values({"green", "green", "blue", "yellow", "red", "red", "yellow", "green", "green"})),
New Column( "count",Numeric,"Continuous",Format( "Best", 12 ),
Formula( Name Expr( Eval( Eval Expr( Col Sum( Row() <= Expr( Row() ), :color ) ) ) ) )),
New Column( "another count",Numeric,"Continuous",Format( "Best", 12 ),
Formula(
n = 0;
For( i = 1, i <= Row(), i++,
If( :color == :color[i], n++ )
);
n;
)
)
);
La formula della terza colonna potrebbe essere più veloce, a scapito della chiarezza, facendola guardare indietro per l'ultima corrispondenza e aggiungendone una a quel conteggio. Chiarezza vs efficienza è un compromesso.

Quindi, vado a correggere il bug scoperto in questo processo: quando una tabella di dati crea uno script per riprodursi (come nell'esempio in alto), deve produrre JSL per riprodurre anche le formule delle colonne. Nel caso in cui la formula della colonna inizi con lo speciale wrapper eval() e si suppone che eval faccia parte della formula, JMP deve aggiungere il nome espr.
aggiornamento 21 aprile 2018: ripara la conversione automatizzata dal blog precedente.