<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />Jemand in der SAS-Gemeinschaften Forum fragte dies. Sie wollten ein Skript schreiben, das einen Graph Builder-Bericht erstellt, ohne vorher zu wissen, wie viele Variablen es geben würde. Das heißt, sie würden nicht wissen, wie viele Variablen es beim Schreiben des Skripts gab, aber das Skript würde zur Laufzeit wissen, wie viele es waren.
Der ursprüngliche Versuch enthielt ein Graph Builder-Skript in einer Schleife über den Spalten, aber es startete Graph Builder N Mal, einmal für jede Schleifeniteration. Stattdessen müssen Sie irgendwie ein einzelnes Skript erstellen, das die variable Anzahl von Spalten berücksichtigt, und dieses Skript dann ausführen. JSL unterstützt diese Art der Metaprogrammierung (ein Skript, das ein anderes Skript erstellt) mit den Funktionen Expr(), Name Expr() und Eval Expr(). Dies sind ziemlich fortgeschrittene Funktionen, aber auch ziemlich leistungsfähig.
Zuerst erstellen wir einen repräsentativen Graph Builder-Bericht und speichern sein Skript:
Graph Builder(
Show Control Panel( 0 ),
Variables(
X( :Country ),
Y( :Score, Side( "Right" ) ),
Y( :Long Jump, Position( 1 ) ),
Y( :Shot Put, Position( 1 ) )
),
Elements(
Points( X, Y( 2 ), Y( 3 ), Legend( 1 ) ),
Line( X, Y( 1 ), Legend( 2 ) )
)
);
Dann notieren wir uns die Teile, die wir parametrisieren möchten – in diesem Fall die Y-Variablen – und verwenden ein Skript, um diesen Teil basierend auf Laufzeitinformationen zu erstellen, und fügen ihn dann in den Gesamtausdruck ein.
// a table with lots of columns
dt = Open( "$SAMPLE_DATA/Decathlon.jmp" );
// an expression for the graph's variables
vars = Expr( Variables( X( :Country ), Y( :Score, Side( "Right" ) ) ) );
// an expression for Points elements
points = Expr( Points( X, Jitter( 1 ) ) );
// a loop to programmitically insert variables into those expressions
first col = 4;
last col = 6;
For( i = first col, i <= last col, i++,
Insert Into( vars, Eval Expr( Y( Expr( Column( dt, i ) ), Position( 1 ) ) ) );
Insert Into( points, Eval Expr( Y( Expr( i - first col + 2 ) ) ), 1 + i - first col );
);
//Show( vars, points );
// build the Graph Builder expression from those
gb = Eval Expr(
Graph Builder(
Show Control Panel( 0 ),
Expr( Name Expr( vars ) ),
Elements( Expr( Name Expr( points ) ), Line( X, Y( 1 ) ) )
)
);
//show( gb );
gb; // execute the expression
Es gibt Möglichkeiten, den gleichen Effekt zu erzielen. Eine ähnliche, aber oft einfacher zu verstehende Technik besteht darin, das Skript als Textzeichenfolge zu erstellen und dann Parse() und Eval() darauf aufzurufen, wenn Sie fertig sind. Ein anderer Weg: Graph Builder unterstützt auch Nachrichten wie Add Variable, die einen bereits erstellten Graph Builder-Bericht ändern können.