Operazioni arbitrarie (funzioni, ecc.) su ciascun elemento di un elencoC'è un modo più semplice per applicare la stessa funzione su ogni elemento di un elenco piuttosto che scorrere un elenco?
Per esempio:
stringlist = {"1", "2"};
numericlist = {};
for (i = 1, i<=N Items(stringlist), i++,
numericlist[i] = Num(stringlist[i])
);
show(numericlist);C'è qualcosa di più semplice, qualcosa come dire semplicemente:
numericlist = Num(stringlist);
ma questo ovviamente non funziona. Ogni altro modo?
PS Appena trovato per ogni nuova funzione in JMP 16, sfortunatamente sono ancora su JMP 15
SceneggiaturaRe: Operazioni arbitrarie (funzioni, ecc.) su ogni elemento di un elencoSe il tuo caso è così, potresti evitare di eseguire il ciclo almeno per la trasformazione usando Parse() (sebbene potrebbe essere più veloce scorrere la stringa).
Names Default To Here(1);<BR />str = "120, 130, 160, 120, 300, 200";
numList = Parse("{" || str ||"}");
Show(numList[1], numList[2]);Come tabella dati:
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(12),
Compress File When Saved(1),
New Column("Column 1",
Character,
"Nominal",
Set Values(
{"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200",
"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200",
"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200",
"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200",
"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200",
"120, 130, 160, 120, 300, 200", "120, 130, 160, 120, 300, 200"}
)
)
);
dt << New Column("numlist", Expression, << set each value(Parse("{" || :Column 1|| "}")));
numListList = dt:numList << get as matrix;
Show(numListList, numListList[1], numListList[1][1]);Re: Operazioni arbitrarie (funzioni, ecc.) su ogni elemento di un elencoGrazie ragazzi!
Questo è bellissimo.
In realtà ho trovato JMP16 nella nostra intranet, il reparto IT ha detto che stavano solo preparando le istruzioni di installazione e rilasciandole ufficialmente. Quindi sono andato avanti e l'ho installato comunque.
Le mie attività effettive erano (erano) un po' più complicate, ad esempio, in un caso avevo un elenco di stringhe di tipo
"120, 130, 160, 120, 300, 200"
I dati effettivi sarebbero una colonna con ogni riga con quel tipo di stringa (solo molto molto più lunga)
Avevo bisogno di trasformarlo in un elenco di elenchi di numeri. Quindi avevo bisogno di leggere quella colonna in un elenco iniziale, quindi applicare Words() su questo elenco iniziale per ottenere un elenco di elenchi di stringhe e quindi Num() per ottenere ogni stringa in un numero. Ciò significa due cicli annidati.
Per ora l'ho fatto con due cicli For Each, ma lasciami esaminare i suggerimenti che hai pubblicato qui. Non sono mai riuscito a comprendere Expr() - credo di aver bisogno di dargli un'altra possibilità.
Grazie!
Re: Operazioni arbitrarie (funzioni, ecc.) su ogni elemento di un elenco@miguello ,
@jthi ti ha dato risposte eccellenti (complimenti).Anch'io ero così entusiasta della funzione TransformEach di JMP 16.
Di seguito è riportata una parte modificata di uno script scritto per versioni molto precedenti di JMP e pubblicato per JMP13. Molti dei miei ex colleghi usavano la funzione LFUNC (il nome è l'abbreviazione di funzione elenco).Il nome e la sintassi di JMP 16 "TransformEach" sono così buoni. Tuttavia, se uno qualsiasi degli elementi dell'elenco è del tipo errato per la trasformazione specificata, viene restituito solo un errore... una funzione Try() può risolverlo.
Quindi, nel caso in cui questo potrebbe essere di qualche utilità fino a quando non arrivi a JMP 16, lo pubblico.Basta salvare la parte di codice della definizione della funzione in un file e utilizzare Include() in qualsiasi script di cui hai bisogno.
// JSL Companion: Applications of the JMP Scripting Language
// Title: JSLC_CustomListFunctions.jsl
// Version: Windows JMP® 13.2.0
// Purpose: Provides examples of writing user functions.
/*Notes:
These functions are provided for learning as well as utility.
See Chapter 5 and 5_Extra_CustomListFunctions.jsl");
The script will define 2 functions. After each is a comment
block /*: Usage & Test examples ... --- end Test*/. Remove
The comment block and run the examples one line at a time. Open
the embedded log or have the log window visible to see
the results.
Motivation:
As seen in Chapter 5, a numeric function on a single layer
list of numbers, or a vector, or a matrix, will return the
same object with the function applied to each item. For example,
xx = Sqrt({1,2,3,4,9}); //xx = {1, 1.4142135623731, 1.73205080756888, 2, 3}
We have suggested that the same apply to String functions (that operate
on a single item) on a list of text. What we would like is
xx = Substr({"Quaker", "Minnesota", "Nebraska"}, 1,1); would return
xx = {"Q", "M", "N"}. However, currently most JMP String functions do not
allow list agruments.
Functions defined here, are:
- LFunc( mylist, expr); where expression is like expr(Substr(x,1,1)).
{LIKE function notes removed}
LFunc can save writing for-loops, Like save looking up the REGEX syntax.
*/
//------LFunc-------------------------------------------------------------------
Lfunc = Function( {xList, fExpr/*ex. Expr(Contains(x,"h"))*/},
{x = {}, i = 1, errCode = 0, errStr = "\!NError bad argument", newExpr},
If( !Is List( xList ),
errCode = 1
);
If(
Type( Name Expr( fExpr ) ) == "Name",
//if Name then JMP does not recognize the function
tmp = Trim( Char( Name Expr( fExpr ) ) );
//extract the function and check if it is contained in the global namespace, if not error!
If( Namespace( "global" ) << Contains( Word( 1, tmp, ":(" ) ) == 0,
errCode = errCode + 2
);,
Type( Name Expr( fExpr ) ) != "Expression", errCode = errCode + 2
);
//catches typos, returns Name if not a valid function
//catches typos, returns Name if not a valid function
If( !Is Expr( Name Expr( fExpr ) ),
errCode = errCode + 2
); //catches syntax
If(
!errCode,
For( i = 1, i <= N Items( xList ), i++,
newExpr = Substitute( Name Expr( fExpr ), Expr( x ), xList[i] );
Insert Into( x, Try( newExpr, Empty() ) );
),
errCode == 1, Write( errStr || "(1) not a list \!N" ),
errCode == 2, Write( errStr || "(2) not a valid expression \!N" ),
errCode == 3, Write( errStr || "s (1) is not a list and (2) is not a valid expression \!N" )
);
x//return x
;
); //End Lfunc
//------------------------------------------------------------------------------
//Usage & Test ...remove the slash asterisk and run in segments, results are in the log
//------------------------------------------------------------------------------
myList1={"john", "harry", "huh","ah ha", "xyx", , "a", "h", 7, [1,7]};
/* example below returns a list of numeric values, one value for each item in the list
n =>1st location of h, 0 => does not contain "h", Empty() => the item is not
a valid argument for that expression.
*/
zz1 = Lfunc(myList1,Expr(Contains(x,"h")));
show(zz1);
myList2={"john", "harry", "huh","ah ha", "xyx", , "a", "h"};
zz2=Lfunc(myList2, Expr(Uppercase(x)));
show(zz2);
//-----------------------------------------------------------------------------------------
/* returns a list of how many words are in each string
[] -> no occurrences
Empty() => the expression is not valid for that item.
*/
zz3 = Lfunc(mylist2, expr(nitems(words(x))));
show(zz3);
//-----------------------------------------------------------------------------------------
/* This specified function requires numeric arguments
Empty() => the expression is not valid for that item.
A numeric function applied to a matrix returns a matrix
of the results applied on each element in the matrix.
Only the last 2 items are valid arguments for Log()
*/
zz4 = Lfunc(mylist1, expr(log(x)));
show(zz4);
//----------------Error Checking---------------------------------------------------------------
/* Uncomment the code below to show the error capture and reporting */
//zz = Lfunc("oh johhny", Expr(Contains(x,"h")) ); //not a list
//zz = Lfunc({"oh johhny"}, Expr(Contians(x,"h")) ); //type not a valid expr due to typo
//zz = Lfunc("oh johhny", Expr(Contians(x,"h")) ); //not a list and not a valid expr
Re: Operazioni arbitrarie (funzioni, ecc.) su ogni elemento di un elencoCome hai già notato, JMP16 aiuterà con questo con For Each e Transform Each. Se devi farlo molte volte, potresti creare funzioni personalizzate per eseguire le attività?
Names Default To Here(1);
charToNum = function({tempList}, {Default Local},
newList = {};
For(i = 1, i <= N Items(tempList), i++,
newList[i] = Num(tempList[i]);
);
return(newList);
);
a = {"1", "2"};
b = charToNum(a);
show(b);
Modificare:
Puoi anche creare funzioni più complicate che potrebbero gestire diverse trasformazioni. Molto probabilmente sarà eccessivo e non lo consiglierei davvero (creerei semplicemente funzioni diverse per trasformazioni diverse).
Ecco un esempio di come si potrebbe fare:
Names Default To Here(1);
transformList = function({tempList, transformExpression}, {Default Local},
newList = {};
For(i = 1, i <= N Items(tempList), i++,
val = tempList[i];
newList[i] = transformExpression
);
return(newList);
);
a = {"1", "2", "100"};
b = transformList(a, Expr(Num(val)));
c = transformList(b, Expr(Multiply(val, 10)));
d = transformList(c, Expr(Char(val)));
Show(a,b,c,d);
//can also use custom functions with transformList
padZero = function({tempValue}, {Default Local},
if(Length(tempValue) < 2,
tempValue = "0" || tempValue;
);
return(tempValue)
);
e = transformList(a, Expr(padZero(val)));
Show(e);
f = transformList(e, Expr(Length(val)));
Show(f);