Hola, he leído las publicaciones sobre las funciones JSL como alternativa a las macros SAS, pero cuando intenté crear una para recorrer un código varias veces con diferentes valores para una variable, ingresé en un bucle sin fin. En el siguiente código, hago tres conjuntos de datos y luego quiero ejecutar el siguiente código para cada grupo. ¿Es esto posible con una función JSL? ¡Gracias!
Data Table( "CSTtable_ad_all1" ) << set name( "CSTtableall" );
//make data set with AI and without AI for table1 summary stats
Data Table( "CSTtableall" ) << select where( :ai == 1 );
Data Table( "CSTtableall" ) << subset( selected rows( 1 ), selected columns( 0 ), output table( "CSTtableai" ) );
Data Table( "CSTtableall" ) << select where( :ai == 0 );
Data Table( "CSTtableall" ) << subset( selected rows( 1 ), selected columns( 0 ), output table( "CSTtableno" ) );
//create summary statistics for CST table; this is the beginning of the code I would like to run through three times
summall = Data Table( "CSTtableall" ) << Summary(
Min( :age ),
Min( :mmesumactiveperday ),
Min( :AM_cort1 ),
Min( :durationofexp ),
Min( :durationofexp90 ),
Min( :cum_opioid_ex ),
Min( :cum_opioid_ex90 ),
Min( :max_cort ),
Max( :age ),
Max( :mmesumactiveperday ),
Max( :AM_cort1 ),
Max( :durationofexp ),
Max( :durationofexp90 ),
Max( :cum_opioid_ex ),
Max( :cum_opioid_ex90 ),
Max( :max_cort ),
Mean( :age ),
Mean( :mmesumactiveperday ),
Mean( :AM_cort1 ),
Mean( :durationofexp ),
Mean( :durationofexp90 ),
Mean( :cum_opioid_ex ),
Mean( :cum_opioid_ex90 ),
Mean( :max_cort ),
Std Dev( :age ),
Std Dev( :mmesumactiveperday ),
Std Dev( :AM_cort1 ),
Std Dev( :durationofexp ),
Std Dev( :durationofexp90 ),
Std Dev( :cum_opioid_ex ),
Std Dev( :cum_opioid_ex90 ),
Std Dev( :max_cort ),
Freq( "None" ),
Weight( "None" )
);
stackall = summall <<
Stack(
columns(
:Name( "Min(age)" ),
:Name( "Min(mmesumactiveperday)" ),
:Name( "Min(AM_cort1)" ),
:Name( "Min(durationofexp)" ),
:Name( "Min(durationofexp90)" ),
:Name( "Min(cum_opioid_ex)" ),
:Name( "Min(cum_opioid_ex90)" ),
:Name( "Min(max_cort)" ),
:Name( "Max(age)" ),
:Name( "Max(mmesumactiveperday)" ),
:Name( "Max(AM_cort1)" ),
:Name( "Max(durationofexp)" ),
:Name( "Max(durationofexp90)" ),
:Name( "Max(cum_opioid_ex)" ),
:Name( "Max(cum_opioid_ex90)" ),
:Name( "Max(max_cort)" ),
:Name( "Mean(age)" ),
:Name( "Mean(mmesumactiveperday)" ),
:Name( "Mean(AM_cort1)" ),
:Name( "Mean(durationofexp)" ),
:Name( "Mean(durationofexp90)" ),
:Name( "Mean(cum_opioid_ex)" ),
:Name( "Mean(cum_opioid_ex90)" ),
:Name( "Mean(max_cort)" ),
:Name( "Std Dev(age)" ),
:Name( "Std Dev(mmesumactiveperday)" ),
:Name( "Std Dev(AM_cort1)" ),
:Name( "Std Dev(durationofexp)" ),
:Name( "Std Dev(durationofexp90)" ),
:Name( "Std Dev(cum_opioid_ex)" ),
:Name( "Std Dev(cum_opioid_ex90)" ),
:Name( "Std Dev(max_cort)" ),
),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Number of Series( 4 ),
Output Table Name( "Table 1 All" ),
Contiguous
);
//stackall << Delete Column( :N Rows );
stackall << New Column( "Parameter", character, formula( Word( 2, :Label, "()" ) ) );
stackall << Move Selected Columns( {“Parameter”}, To First );
Column( Data Table( "Table 1 All" ), "Parameter" ) << Delete Formula;
stackall << Delete Column( :Label );
stackall << Delete Column( :Label 2 );
stackall << Delete Column( :Label 3 );
stackall << Delete Column( :Label 4 );
Column( Data Table( "Table 1 All" ), "Data" ) << Set Name( "Min" );
Column( Data Table( "Table 1 All" ), "Data 2" ) << Set Name( "Max" );
Column( Data Table( "Table 1 All" ), "Data 3" ) << Set Name( "Mean" );
Column( Data Table( "Table 1 All" ), "Data 4" ) << Set Name( "St Dev" );
Close( summall, no save );
He reelaborado su código para que sea más conciso y para que se ejecute una vez para cada una de las 3 tablas de datos creadas.Probé esto en una tabla de datos de muestra.Puede abrirlo y ejecutarlo como está.El código que usa una tabla de datos de muestra se adjunta a esta respuesta.A continuación se muestra mi reelaboración de su código original.
Names Default To Here( 1 );
dt = Data Table( "CSTtable_ad_all1" );
dt << set name( "CSTtableall" );
//make data set with AI and without AI for table1 summary stats
dt << select where( :ai == 1 );
dt2 = dt << subset( selected rows( 1 ), selected columns( 0 ), output table( "CSTtableai" ) );
dt << select where( :ai == 0 );
dt3 = dt << subset( selected rows( 1 ), selected columns( 0 ), output table( "CSTtableno" ) );
tableList = {dt, dt2, dt3};
createSummary = Function( {theTable, outputTable},
//create summary statistics for CST table; this is the beginning of the code I would like to run through three times
summall = eval(theTable) << Summary(
Min( :age, :mmesumactiveperday, :AM_cort1, :durationofexp, :durationofexp90, :cum_opioid_ex, :cum_opioid_ex90, :max_cort ),
Max( :age, :mmesumactiveperday, :AM_cort1, :durationofexp, :durationofexp90, :cum_opioid_ex, :cum_opioid_ex90, :max_cort ),
Mean( :age, :mmesumactiveperday, :AM_cort1, :durationofexp, :durationofexp90, :cum_opioid_ex, :cum_opioid_ex90, :max_cort ),
Std Dev( :age, :mmesumactiveperday, :AM_cort1, :durationofexp, :durationofexp90, :cum_opioid_ex, :cum_opioid_ex90, :max_cort ),
Freq( "None" ),
Weight( "None" )
);
colList = summall << get column names( string );
Remove From( colList, 1, 1 );
stackall = summall << Stack(
columns( Eval( colList ) ),
Source Label Column( "Label" ),
Stacked Data Column( "Data" ),
Number of Series( 4 ),
Output Table Name( "Table 1 All" ),
Contiguous
);
//stackall << Delete Column( :N Rows );
stackall << New Column( "Parameter", character, formula( Word( 2, :Label, "()" ) ) );
stackall << Move Selected Columns( {“Parameter”}, To First );
Column( Data Table( "Table 1 All" ), "Parameter" ) << Delete Formula;
stackall << Delete Columns( {:Label, :Label 2, :Label 3, :Label 4} );
Column( stackall, "Data" ) << Set Name( "Min" );
Column( stackall, "Data 2" ) << Set Name( "Max" );
Column( stackall, "Data 3" ) << Set Name( "Mean" );
Column( stackall, "Data 4" ) << Set Name( "St Dev" );
Close( summall, no save );
stackall << set name( outputTable );
);
For( i = 1, i <= N Items( tableList ), i++,
createSummary( tableList[i], eval(tableList[i]) << get name || "_Output" )
);
Muchas gracias funcionó a la perfección