Ciao, ho letto i post sulle funzioni JSL in alternativa alle macro SAS, ma quando ho provato a crearne uno per scorrere un codice più volte con valori diversi per una variabile sono entrato in un ciclo infinito. Nel codice seguente creo tre set di dati e quindi voglio eseguire il codice successivo per ogni gruppo. È possibile con una funzione JSL? Grazie!
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 );
Ho rielaborato il tuo codice per essere più conciso e per eseguirlo una volta per ciascuna delle 3 tabelle di dati create.L'ho testato su una tabella di dati di esempio.Puoi aprirlo ed eseguirlo così com'è.Il codice che utilizza una tabella dati di esempio è allegato a questa risposta.Di seguito è riportata la mia rielaborazione del codice originale.
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" )
);
Grazie mille ha funzionato perfettamente