回复全部:如何为 Graph Builder 编写动态内容脚本SAS 社区论坛上有人问过这个问题。他们想写一个脚本,在创建 Graph Builder 报表时,无需事先知道有多少个变量。也就是说,他们在写脚本时不知道有多少个变量,但脚本在运行时知道有多少个变量。
最初的尝试是在列循环中包含一个 Graph Builder 脚本,但它会启动n次 Graph Builder,每次循环迭代都会启动一次。因此,您需要以某种方式构建一个脚本来处理可变数量的列,然后运行该脚本。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 报告。
回复:回复所有人:如何为 Graph Builder 编写动态内容脚本dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "col1", Numeric, Continuous, Set Formula( Col Shuffle() ) );
dt << New Column( "col2", Numeric, Continuous, Set Formula( Col Shuffle() ) );
dt << New Column( "col3", Numeric, Continuous, Set Formula( Col Shuffle() ) );
m1 = 1; m2 = 180; m0 = 10;
one=Expr(Variables( X( Transform Column( "Row", Formula( Row() ))) , Y( :height ) ));two=Expr(Elements( Position( 1, 1 ), Bar( X, Y, Legend( 5 ) ) ) );thr=Expr( Dispatch( {}, "height", ScaleBox, {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} ));
first co = 5;last col = 8;
For( i = first co, i <= last col, i++,
Insert Into( one, Eval Expr( Y( Expr( Column( dt, i ) ) ) ) );
Insert Into( two, Eval Expr(Elements( Position( 1, Expr(i-3 )), Bar( X, Y, Legend( Expr(1+i )) ) ) ));
Insert Into( thr, Eval Expr( Dispatch( {}, Column(Expr(i))<
<GET name=""></GET>
回复:回复所有人:如何为 Graph Builder 编写动态内容脚本谢谢专家!
我尝试用同样的方法修改JSL,但仍然不起作用。
我只是制作了一个简单的条形图,并为每个条形使用了相同的上限值和下限值。
请教高手帮忙如何完成这个动态列命名?非常感谢!
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
dt << New Column( "col1", Numeric, Continuous, Set Formula( Col Shuffle() ) );
dt << New Column( "col2", Numeric, Continuous, Set Formula( Col Shuffle() ) );
dt << New Column( "col3", Numeric, Continuous, Set Formula( Col Shuffle() ) );
m1 = 1; m2 = 180; m0 = 10;
p1 = dt << Graph Builder(
Size( 519, 841 ),
Show Control Panel( 0 ),
Show Legend( 0 ),
Show Title( 0 ),
Show Footer( 0 ),
Show X Axis( 0 ),
Show Y Axis( 0 ),
Show X Axis Title( 0 ),
Variables( X( Transform Column( "Row", Formula( Row() ) ) ), Y( :height ), Y( :weight ), Y( :col1 ), Y( :col2 ), Y( :col3 ) ),
Elements( Position( 1, 1 ), Bar( X, Y, Legend( 5 ) ) ),
Elements( Position( 1, 2 ), Bar( X, Y, Legend( 6 ) ) ),
Elements( Position( 1, 3 ), Bar( X, Y, Legend( 7 ) ) ),
Elements( Position( 1, 4 ), Bar( X, Y, Legend( 8 ) ) ),
Elements( Position( 1, 5 ), Bar( X, Y, Legend( 9 ) ) ),
SendToReport(
Dispatch( {}, "height", ScaleBox, {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} ),
Dispatch( {}, "weight", ScaleBox, {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} ),
Dispatch( {}, "col1", ScaleBox( 2 ), {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} ),
Dispatch( {}, "col2", ScaleBox, {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} ),
Dispatch( {}, "col3", ScaleBox, {Min( m1 ), Max( m2 ), Inc( m0 ), Minor Ticks( 1 )} )
)
);
