<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />有人在SAS 社區論壇問這個。 他們想編寫一個腳本來創建 Graph Builder 報告,但事先不知道會有多少變量。 也就是說,他們在編寫腳本時不會知道有多少變量,但腳本會在運行時知道有多少。
最初的嘗試在列循環中包含一個 Graph Builder 腳本,但它正在啟動 Graph Builder n次,每次循環迭代一次。 相反,您需要以某種方式構建一個腳本來解釋可變數量的列,然後運行該腳本。 JSL 使用函數 Expr()、Name Expr() 和 Eval Expr() 支持這種元編程(一個腳本創建另一個腳本)。 這些是非常高級的功能,但也非常強大。
首先我們製作一個有代表性的 Graph Builder 報告並保存它的腳本:
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 ) )
)
);
然後我們記下我們想要參數化的部分——在本例中是 Y 變量,並使用腳本根據運行時信息創建該部分,然後將其粘附到整體表達式中。
// 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
有多種方法可以獲得相同的效果。 一種類似但通常更容易理解的技術是將腳本構建為文本字符串,然後在完成後調用 Parse() 和 Eval()。 另一種方式:Graph Builder 還支持像 Add Variable 這樣的消息,它可以修改一個已經構建好的 Graph Builder 報告。