AutoReg



Premise

Below you can find the SAS macro code classizz (the main procedure) and two utility macros: simpson_c and mod_b_meno_a.
If you want, you can download the entire code in text format (AutoReg.txt), as zipped text (AutoReg_txt.zip), as pdf (AutoReg.pdf) or zipped pdf (AutoReg_pdf.zip).

Please remember that every code you find in this website, even when not explicitly written, is distributed under GNU General Public License, version 3.



SAS Code

/*
AutoReg.
Procedura per la stima quasi automatica di un modello di regressione.
Versione 0.11.7 (28 Luglio 2013)
Copyright (C) Daniele Rampoldi

This program is free software: you can redistribute it and/or modify it under the terms
 of the GNU General Public License, version 3, as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License version 3 along with this program.
If not, see http://www.gnu.org/licenses/ .

Daniele Rampoldi
www.zxdr.it
rampoldid@zxdr.it
rampoldid@yahoo.it

La via del saggio è agire, ma non competere (Lao Tzu)
*/



%macro simpson_c(vara, varb, utia, utib, prefisso, taglio);

proc sql;
 create table &prefisso._bb11 as
  select &vara, &varb, count(*) as num11
  from &prefisso._pt
  group by &vara, &varb;

 create table &prefisso._bb10 as
  select &vara, count(*) as num10
  from &prefisso._pt
  group by &vara;

 create table &prefisso._bb01 as
  select &varb, count(*) as num01
  from &prefisso._pt
  group by &varb;
quit;

proc sql;
 create table &prefisso._cc2 as
  select a.*, b.num10
  from &prefisso._bb11 a left join &prefisso._bb10 b on
	(a.&vara = b.&vara);

 create table &prefisso._cc as
  select a.*, b.num01
  from &prefisso._cc2 a left join &prefisso._bb01 b on
	(a.&varb = b.&varb);
quit;

data &prefisso._dd;
set &prefisso._cc;
 format lambda10j 10.5;
 format lambda01j 10.5;
 if num10 = 1 and num11 = 1 then lambda10j = 1;
  else lambda10j = (num11 * (num11 - 1)) / (num10 * (num10 - 1));
 if num01 = 1 and num11 = 1 then lambda01j = 1;
  else lambda01j = (num11 * (num11 - 1)) / (num01 * (num01 - 1));
run;

proc delete data=&prefisso._bb01 &prefisso._bb10 &prefisso._bb11
	&prefisso._cc &prefisso._cc2;
run;

proc sql;
 create table &prefisso._dd10 as
  select &vara, num10, sum(lambda10j) as lambda10
  from &prefisso._dd
  group by &vara, num10;
quit;

proc sql;
 create table &prefisso._dd01 as
  select &varb, num01, sum(lambda01j) as lambda01
  from &prefisso._dd
  group by &varb, num01;
quit;

data &prefisso._dd10b;
set &prefisso._dd10;
 nlambda10 = num10 * lambda10;
run;

data &prefisso._dd01b;
set &prefisso._dd01;
 nlambda01 = num01 * lambda01;
run;

proc sql;
 create table &prefisso._dd10c as
  select 1 as incrocio, sum(nlambda10) / sum(num10) as lm10
  from &prefisso._dd10b;

 create table &prefisso._dd01c as
  select 1 as incrocio, sum(nlambda01) / sum(num01) as lm01
  from &prefisso._dd01b;
quit;

proc sql;
 create table &prefisso._ee as
  select lm10, lm01
  from &prefisso._dd10c a inner join &prefisso._dd01c b on
	(a.incrocio = b.incrocio);
quit;

data &prefisso._rit;
set &prefisso._ee;
 simpson_plus = (lm10 + lm01) / 2;
 if simpson_plus >= &taglio then val = simpson_plus;
  else val = 0;
run;

proc delete data=&prefisso._dd &prefisso._dd01 &prefisso._dd01b &prefisso._dd01c
	&prefisso._dd10 &prefisso._dd10b &prefisso._dd10c &prefisso._ee;
run;

%mend simpson_c;










%macro mod_b_meno_a(moda, modb, alpha, prefisso);

data &moda._dev;
set &moda;
 if _n_ = 1;
run;

data &modb._dev;
set &modb;
 if _n_ = 1;
run;

proc sql noprint;
create table &prefisso._c1 as
 select criterion, df, value
 from &moda._dev;

create table &prefisso._c2 as
 select criterion, df, value
 from &modb._dev;

create table &prefisso._c3 as
 select a.df as dfa, a.value as vala,
	b.df as dfb, b.value as valb
 from &prefisso._c1 a, &prefisso._c2 b
 where a.criterion = b.criterion;
quit;

data &prefisso._c3;
set &prefisso._c3;
 ddev = valb - vala;
 ddf = dfb - dfa;
 if ddev >0 and ddf > 0 then do;
   p = cdf('CHISQUARE', ddev, ddf);
  end;
 else do;
   p = .;
  end;
 p_inv = sum(1, -p);
run;

proc sql noprint;
 select p_inv format=40.20 into :p
 from &prefisso._c3;
quit;

%let p = &p;

proc delete data=&prefisso._c1 &prefisso._c2 &prefisso._c3;
run;

data &prefisso._rit;
format val 1.;
%if &p < &alpha %then %do;
	 val = 1;
	%end;
 %else %do;
	 val = 2;
	%end;
run;

%mend mod_b_meno_a;










%macro classizz(in=a, taglio_correlazione=0.4, distribuzione=binomial, alfa=0.05, passo=10,
		log_0=log, output_log=log, max_giri=0, max_format=$32767, passi=NIENTE, simpson=1);

%let versione_dr = 00 - v0.11.6 - 13.12.2010 - zxdr;

%put &versione_dr;

%put +++++ Parametri di input +++++;
%put 01 +&in+ (in);
%put 02 +&taglio_correlazione+ (taglio_correlazione);
%put 03 +&distribuzione+ (distribuzione);
%put 04 +&alfa+ (alfa);
%put 05 +&passo+ (passo);
%put 06 +&log_0+ (log_0);
%put 07 +&output_log+ (output_log);
%put 08 +&max_giri+ (max_giri);
%put 09 +&max_format+ (max_format);
%put 10 +&passi+ (passi);
%put 11 +&simpson+ (simpson);

proc printto log=&output_log; run;

%put &versione_dr;

%put +++++ Parametri di input +++++;
%put 01 +&in+ (in);
%put 02 +&taglio_correlazione+ (taglio_correlazione);
%put 03 +&distribuzione+ (distribuzione);
%put 04 +&alfa+ (alfa);
%put 05 +&passo+ (passo);
%put 06 +&log_0+ (log_0);
%put 07 +&output_log+ (output_log);
%put 08 +&max_giri+ (max_giri);
%put 09 +&max_format+ (max_format);
%put 10 +&passi+ (passi);
%put 11 +&simpson+ (simpson);

data &in._tesec;
 inizio = datetime();
 ahora = inizio;
run;

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;

proc printto log=&log_0; run;

%put &versione_dr;

%put +++++ Parametri di input +++++;
%put 01 +&in+ (in);
%put 02 +&taglio_correlazione+ (taglio_correlazione);
%put 03 +&distribuzione+ (distribuzione);
%put 04 +&alfa+ (alfa);
%put 05 +&passo+ (passo);
%put 06 +&log_0+ (log_0);
%put 07 +&output_log+ (output_log);
%put 08 +&max_giri+ (max_giri);
%put 09 +&max_format+ (max_format);
%put 10 +&passi+ (passi);
%put 11 +&simpson+ (simpson);

%put 01 - Controllo dei parametri di input;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

%if %sysfunc(exist(&in)) = 0 %then %do;	/* 01 */
	 %put La tabella &in non esiste.;
	 %goto theend;
	%end;	/* 01 */
%if %sysfunc(index(&taglio_correlazione, -)) ^= 0 or
    %sysfunc(index(&alfa, -)) ^= 0 %then %do;	/* 02 */
	 %put I valori di probabilita e correlazione (&tagliocorrelazione, &alfa) DEVONO essere NON NEGATIVI.;
	 %goto theend;
	%end;	/* 02 */
%if %sysevalf(&taglio_correlazione > 1) or
    %sysevalf(&alfa > 1) %then %do;	/* 03 */
	 %put I valori di probabilita e correlazione (&tagliocorrelazione, &alfa) DEVONO essere MINORI di 1.;
	 %goto theend;
	%end;	/* 03 */


proc printto log=&output_log; run;

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;

proc printto log=&log_0; run;

%put 02 - Caricamento delle variabili da utilizzare;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

proc printto log=&output_log; run;

%let oncamm = 0;

%if "&passi" ^= "NIENTE" %then %do;	/* 03b */
 %if %sysfunc(exist(&passi)) = 0 %then %do;	/* 03b.01 */
	  proc printto log=&log_0; run;
	 %put La tabella &passi non esiste.;
          proc printto log=&output_log; run;
	 %goto theend;
	%end;	/* 03b.01 */

 %let oncamm = 1;
 %let pcamm = 0;

 proc sql noprint;
  select max(passo) into :mpass
  from &passi;
 quit;

 %let mpass = &mpass;

 data &in._s2;
 set &passi;
  %do i=1 %to &mpass;	/* 03b.02 */
   v&i = scan(modello, &i);
  %end;	/* 03b.02 */
  word = %do i=1 %to &mpass;	/* 03b.03 */
	 (v&i ^= '') +
	%end;	/* 03b.03 */
	 0;
 run;

 proc sort data=&in._s2;
  by passo;
 run;

 proc sql noprint;
  select max(word) into :mword
  from &in._s2;
 quit;

 %let mword = &mword;

 %if &mpass > &mword %then %do;	/* 03b.04 */
  data &in._s2;
  set &in._s2;
   drop %do i=%eval(&mword + 1) %to &mpass;	/* 03b.04.01 */
	v&i
       %end;	/* 03b.04.01 */
	;
  run;
 %end;	/* 03b.04 */

 data &in._s2;
 set &in._s2;
  if _N_ = 1 then do;	/* 03b.05 */
   %do i=1 %to &mword;	/* 03b.05.01 */
    retain vo&i;
    vo&i = v&i;
   %end;	/* 03b.05.01 */
   retain wordo;
   wordo = word;
   camm = v1;
  end;	/* 03b.05 */
  %do i=1 %to &mword;	/* 03b.06 */
   if word > wordo then do;	/* 03b.06.01 */
    if v&i ^= '' then do;	/* 03b.06.01.01 */
     if v&i ^= vo&i then do;	/* 03b.06.01.01.01 */
      camm = v&i;
      i = &mword + 1;
      wordo = word;
     end;	/* 03b.06.01.01.01 */
    end;	/* 03b.06.01.01 */
   end;	/* 03b.06.01 */
  %end;	/* 03b.06 */
  %do i=1 %to &mword;	/* 03b.07 */
   vo&i = v&i;
  %end;	/* 03b.07 */
  wordo = word;
 run;

 proc sql noprint;
  select count(*) into :lcamm
  from &in._s2
  where camm ^= '';
 quit;

 %let lcamm = &lcamm;

 proc sql noprint;
  select compress(camm) into :camm1 - :camm&lcamm
  from &in._s2
  where camm ^= '';
 quit;

 proc delete data=&in._s2;
 run;

%end;	/* 03b */

data &in._cond;
 format variabile $70.;
 format condizione &max_format..;
 format classe $100.;
set &in._cond;
 if variabile ^= '';
 variabile = upcase(compress(variabile));
 keep variabile condizione classe;
run;

data &in._var ;
 format name $70.;
set &in._var ;
 if name ^= '';
 name = upcase(compress(name));
 utilizzo = upcase(compress(utilizzo));
 keep name type format formatl formatd utilizzo;
run;

%let ludecla = 0;

proc sql noprint;
 select count(*) into :ludecla
 from &in._var
 where utilizzo = 'R';
quit;

proc printto log=&log_0; run;

%if &ludecla ^= 1 %then %do;	/* 04 */
  %put Non ci possono essere &ludecla variabili risposta.;
  %goto theend;
 %end;	/* 04 */

%if &max_giri = 0 %then %do;	/* 05 */
 proc sql noprint;
  select count(*) into :max_g
  from &in._var
  where utilizzo in ('O' 'C' 'Q' 'X' 'K');
 quit;

 %let max_g = %eval(&max_g*3);
%end;	/* 05 */
%else %do;	/* 06 */
 %let max_g = &max_giri;
%end;	/* 06 */

proc printto log=&output_log; run;


data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;

proc printto log=&log_0; run;

%put 03 - Copia dei file di input;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

proc printto log=&output_log; run;

data &in._passi;
 format passo 10.;
 format modello &max_format..;
 if passo > 0;
run;

data &in._kcl;
 format var_orig $100.;
 format cl_orig $100.;
 format cl_nuova 20.;
 if cl_nuova > 0;
run;

proc sql;
 select name into :ludecla separated by ' '
 from &in._var
 where utilizzo in ('I' 'R' 'O' 'Q' 'X' 'C' 'K');
quit;

data &in._pt;
set &in ;
 keep &ludecla ;
run;

proc sql noprint;
 select count(*) into :n_vrk
 from &in._var
 where compress(utilizzo) = 'K';

 select compress(name) into :vri
  from &in._var
  where compress(utilizzo) = 'R';
quit;

%let n_vrk = &n_vrk;
%let vri = &vri;

%if &n_vrk <= 0 %then %do;	/* 06b */
 %goto finek;
%end;	/* 06b */

proc sql noprint;
 select compress(name), type, format, formatl, formatd into
	:vrk1 - :vrk&n_vrk, :vrkt1 - :vrkt&n_vrk, :vrkfo1 - :vrkfo&n_vrk, :vrkfl1 - :vrkfl&n_vrk, :vrkfd1 - :vrkfd&n_vrk
 from &in._var
 where compress(utilizzo) = 'K';
quit;

%do i=1 %to &n_vrk;	/* 06c */

 data &in._esccon;
 set &in._esccon;
  var1 = upcase(compress(var1));
  var2 = upcase(compress(var2));
 run;

 data &in._esccon2;
  format var1 $70.;
 set &in._esccon;
  if compress(var1) = compress("&&vrk&i") then do;	/* 06c.01a */
    output;
   var1 = compress('K_' || compress("&&vrk&i"));
    output;
  end;	/* 06c.01a */
  else do;	/* 06c.01a2 */
    output;
  end;	/* 06c.01a2 */
 run;

 data &in._esccon3;
  format var2 $70.;
 set &in._esccon2;
  if compress(var2) = compress("&&vrk&i") then do;	/* 06c.01b */
    output;
   var2 = compress('K_' || compress("&&vrk&i"));
    output;
  end;	/* 06c.01b */
  else do;	/* 06c.01b2 */
    output;
  end;	/* 06c.01b2 */
 run;

 data &in._esccon;
 set &in._esccon3;
 run;

 proc delete data=&in._esccon2 &in._esccon3;
 run;

 data &in._vrk;
 set &in._pt;
  keep &vri &&vrk&i;
 run;

 proc sql noprint;
  create table &in._vrk2 as
   select &&vrk&i, sum(&vri) / count(*) as incidenza
   from &in._vrk
   group by &&vrk&i;
 quit;

 data &in._conk;
 set &in._cond;
  if compress(variabile) = compress("&&vrk&i");
 run;

 proc sql noprint;
  select count(*) into :nconk
  from &in._conk;
 quit;

 %let nconk = &nconk;

 proc sql noprint;
  select condizione, classe into :conk1 - :conk&nconk, :clonk1 - :clonk&nconk
  from &in._conk;
 quit;

 data &in._vrk2;
 set &in._vrk2;
  k_&&vrk&i = 1;
  %if &nconk > 0 %then %do;	/* 06c.01 */
    %do j=1 %to &nconk;	/* 06c.01.01 */
      if &&conk&j then do;	/* 06c.01.01.01 */
        k_&&vrk&i = -&j;
       end;	/* 06c.01.01.01 */
     %end;	/* 06c.01.01 */
   %end;	/* 06c.01 */
 run;

 proc sort data=&in._vrk2;
  by k_&&vrk&i incidenza;
 run;

 data &in._vrk2;
 set &in._vrk2;
  retain kk 0;
  retain incid 0;
  if kk <= 0 then do;	/* 06c.02 */
    kk = k_&&vrk&i;
    incid = incidenza;
   end;	/* 06c.02 */
   else if kk > 0 then do;	/* 06c.03 */
     if incidenza = incid then k_&&vrk&i = kk;
      else do;	/* 06c.03.01 */
        kk = kk + 1;
        k_&&vrk&i = kk;
        incid = incidenza;
       end;	/* 06c.03.01 */
    end;	/* 06c.03 */
  drop kk incid;
 run;

 proc sql noprint;
  create table &in._ptk as
   select a.*, b.k_&&vrk&i
   from &in._pt a left join &in._vrk2 b on
	(a.&&vrk&i = b.&&vrk&i);
 quit;

 data &in._pt;
 set &in._ptk;
 run;

 proc delete data=&in._ptk;
 run;

 proc sql noprint;
  select count(distinct k_&&vrk&i) into :nkk
  from &in._vrk2;
 quit;

 %let nkk2 = %sysevalf(1 + (100/&passo), int);

 %if &nkk2 >= &nkk %then %do;	/* 06c.04 */
   proc sql noprint;
    insert into &in._var values ("K_&&vrk&i", 1, '', 0, 0, 'O');
   quit;
  %end;	/* 06c.04 */
 %else %do;	/* 06c.05 */
   proc sql noprint;
    insert into &in._var values ("K_&&vrk&i", 1, '', 0, 0, 'X');
   quit;
  %end;	/* 06c.05 */

 %if &nconk > 0 %then %do;	/* 06c.06 */
   %do j=1 %to &nconk;	/* 06c.06.01 */
     proc sql noprint;
      insert into &in._cond values ("K_&&vrk&i", "K_&&vrk&i = -&j", "-&j");
     quit;
    %end;	/* 06c.06.01 */
  %end;	/* 06c.06 */

 %let vrkfo&i = &&vrkfo&i;
 %let vrkfl&i = &&vrkfl&i;
 %let vrkfd&i = &&vrkfd&i;

 %if &&vrkt&i = 1 %then %do;	/* 06c.07 */

  %if "&&vrkfo&i" = "" and "&&vrkfl&i" = "0" and "&&vrkfd&i" = "0" %then %do;	/* 06c.07.01 */
   proc sql noprint;
    create table &in._kcl0 as
     select "&&vrk&i" as var_orig, compress(put(&&vrk&i, best.)) as cl_orig,
	k_&&vrk&i as cl_nuova
     from &in._vrk2;
   quit;
  %end;	/* 06c.07.01 */

  %else %do;	/* 06c.07.02 */
   proc sql noprint;
    create table &in._kcl0 as
     select "&&vrk&i" as var_orig, compress(put(&&vrk&i, &&vrkfo&i..&&vrkfl&i...&&vrkfd&i )) as cl_orig,
	k_&&vrk&i as cl_nuova
     from &in._vrk2;
   quit;
  %end;	/* 06c.07.02 */

 %end;	/* 06c.07 */

 %else %if &&vrkt&i = 2 %then %do;	/* 06c.08 */
  proc sql noprint;
   create table &in._kcl0 as
    select "&&vrk&i" as var_orig, strip(put(&&vrk&i, $100.)) as cl_orig,
	k_&&vrk&i as cl_nuova
    from &in._vrk2;
  quit;
 %end;	/* 06c.08 */

 data &in._kcl;
 set &in._kcl &in._kcl0;
 run;

 proc delete data=&in._vrk &in._vrk2 &in._conk &in._kcl0;
 run;

%end;	/* 06c */

%finek:

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;


proc printto log=&log_0; run;

%put 04a - Classizzazione delle variabili O;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;


proc printto log=&output_log; run;

%let ludecla = 0;

proc sql noprint;
 select max(length(classe)) into :ludecla
 from &in._cond;
quit;

%if &ludecla = . %then %do;
  %let ludecla = 0;
 %end;

%let ludecla = %eval(&ludecla+2);

%if %eval(&ludecla < 50) %then %do;	/* 07 */
	%let ludecla = 50;
 %end;	/* 07 */



data &in._var_b;
set &in._var;
 if utilizzo = 'O';
run;

%let o_numvarcl = 0;

data _NULL_;
set &in._var_b end=fine;
 call symputx('o_classizz'!!strip(_n_),name);
 call symputx('o_varcl'!!strip(_n_),'CL_'!!strip(name));
 if fine then call symputx('o_numvarcl',(_n_));
run;

proc delete data=&in._var_b ;
run;

%if %symexist(o_numvarcl) = 0 or &o_numvarcl = 0 %then %goto o_noclassizz;

%let num_condiz = 0;

data _NULL_;
set &in._cond end=fine;
 call symputx('condiz'!!strip(_n_), condizione);
 call symputx('v_condiz'!!strip(_n_), compress(variabile));
 call symputx('cl_condiz'!!strip(_n_), strip(classe));
 if fine then call symputx('num_condiz',(_n_));
run;


data &in._pt;
set &in._pt;
 %do i=1 %to &o_numvarcl;	/* 07b */
   &&o_varcl&i.._z = 0;
   format &&o_varcl&i $&ludecla..;
   format &&o_varcl&i.._b 10.;
   &&o_varcl&i = compress(put(&&o_classizz&i, best.));
   &&o_varcl&i.._b = &&o_classizz&i;
   if &&o_varcl&i.._b <= 0 then &&o_varcl&i.._z = 1;
   %if &num_condiz > 0 %then %do;	/* 07b.01 */
     %do j=1 %to &num_condiz;	/* 07b.01.01 */
      %if %upcase(&&v_condiz&j) = %upcase(&&o_classizz&i) %then %do;	/* 07b.01.01.01 */
	if &&condiz&j then do;	/* 07b.01.01.01.01 */
	  &&o_varcl&i = "&&cl_condiz&j";
	  &&o_varcl&i.._b = -&j;
	  &&o_varcl&i.._z = 0;
	 end;	/* 07b.01.01.01.01 */
      %end;	/* 07b.01.01.01 */
     %end;	/* 07b.01.01 */
    %end;	/* 07b.01 */
  %end;	/* 07b */
run;


%do i=1 %to &o_numvarcl;	/* 07c */
  %let allarme = 0;

  proc sql noprint;
   select max(&&o_varcl&i.._z) into :allarme
   from &in._pt;
  quit;

  %if &allarme = 1 %then %do;	/* 07c.01 */
   data &in._ptr;
   set &in._pt;
    if &&o_varcl&i.._z = 1 or &&o_varcl&i.._b > 0;
    keep &&o_classizz&i;
   run;

   proc sort data=&in._ptr nodup;
    by &&o_classizz&i;
   run;

   data &in._ptr;
   set &in._ptr;
    retain cla_new 1;
    output;
    cla_new = cla_new + 1;
   run;

   proc sql;
    create table &in._ptr2 as
     select a.*, b.cla_new
     from &in._pt a left join &in._ptr b on
	(a.&&o_classizz&i = b.&&o_classizz&i);
   quit;

   data &in._pt;
   set &in._ptr2;
    if cla_new ^= . then &&o_varcl&i.._b = cla_new;
    drop cla_new;
   run;

   proc delete data=&in._ptr &in._ptr2;
   run;
  %end;	/* 07c.01 */

  data &in._pt;
  set &in._pt;
   drop &&o_varcl&i.._z;
  run;
%end;	/* 07c */

%o_noclassizz:

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;


proc printto log=&log_0; run;

%put 04b - Classizzazione delle variabili X;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;


proc printto log=&output_log; run;

data &in._var_b;
set &in._var;
 if utilizzo = 'X';
run;

%let numvarcl = 0;

data _NULL_;
set &in._var_b end=fine;
 call symputx('classizz'!!strip(_n_),name);
 call symputx('varcl'!!strip(_n_),'CL_'!!strip(name));
 call symputx('formato'!!strip(_n_),format);
 call symputx('lform'!!strip(_n_),formatl);
 call symputx('dform'!!strip(_n_),formatd);
 if fine then call symputx('numvarcl',(_n_));
run;

proc delete data=&in._var_b ;
run;

%if %symexist(numvarcl) = 0 or &numvarcl = 0 %then %goto noclassizz;

%let num_condiz = 0;

data _NULL_;
set &in._cond end=fine;
 call symputx('condiz'!!strip(_n_), condizione);
 call symputx('v_condiz'!!strip(_n_), compress(variabile));
 call symputx('cl_condiz'!!strip(_n_), strip(classe));
 if fine then call symputx('num_condiz',(_n_));
run;


%do i=1 %to &numvarcl ;	/* 08 */

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;


 %put 05.&i - Variabile &&classizz&i;
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 data &in._pt_temp;
 set &in._pt;
 %if &num_condiz > 0 %then %do;	/* 08.01 */
  %do j=1 %to &num_condiz;	/* 08.01.01 */
	 %if %upcase(&&v_condiz&j) = %upcase(&&classizz&i) %then %do;	/* 08.01.01.01 */
		 if &&condiz&j then delete;
		%end;	/* 08.01.01.01 */
	%end;	/* 08.01.01 */
   %end;	/* 08.01 */
 keep &&classizz&i ;
 run;

 proc sql noprint;
  select count(*) into :num_cl
  from &in._pt_temp;
 quit;

 %if &num_cl = 0 %then %goto nonormali;

 proc univariate data=&in._pt_temp noprint;
 var &&classizz&i ;
 output out=&in._pt_temp2
	pctlpre= p_
	pctlpts=0 to 100 by &passo ;
 run;


 proc transpose data=&in._pt_temp2 out=&in._pt_temp3 ;
 run;

 proc sort data=&in._pt_temp3 ;
 by col1;
 run;

 data &in._quanti ;
 set &in._pt_temp3 ;
  retain val_prec .;
  classe = _n_;
   output;
  val_prec = col1;
 run;

 proc sort data=&in._quanti ;
  by classe;
 run;

 proc sql noprint;
  select count(*) into :num_cl
   from &in._quanti ;

  select col1 into :max_cl1 - :max_cl%trim(&num_cl)
   from &in._quanti ;

  select val_prec into :min_cl1 - :min_cl%trim(&num_cl)
   from &in._quanti ;

  select classe into :nome_cl1 - :nome_cl%trim(&num_cl)
   from &in._quanti ;
 quit;

 data _NULL_;
 set &in._quanti ;
  call symputx('min_classe'!!strip(_n_),val_prec);
  call symputx('max_classe'!!strip(_n_),col1);
 run;

 proc delete data=&in._quanti ; run;

 data &in._pt;
 set &in._pt;
  format &&varcl&i $&ludecla..;
  format &&varcl&i.._b 10.;
  &&varcl&i = '0';
  &&varcl&i.._b = -1;
  %do j=1 %to &num_cl ;	/* 08.03 */
   %if &j = 1 %then %do;	/* 08.03.01 */
	 if &&classizz&i <= &&max_classe&j then do;	/* 08.03.01.01 */
		 &&varcl&i = "Min < &&classizz&i <= &&max_cl&j";
		 &&varcl&i.._b = &&nome_cl&j;
		end;	/* 08.03.01.01 */
	%end;	/* 08.03.01 */
    %else %if &j = &num_cl %then %do;	/* 08.03.02 */
		 if &&classizz&i > &&min_classe&j then do;	/* 08.03.02.01 */
			 &&varcl&i = "&&min_cl&j < &&classizz&i <= Max";
			 &&varcl&i.._b = &&nome_cl&j;
			end;	/* 08.03.02.01 */
		%end;	/* 08.03.02 */
	   %else %do;	/* 08.03.03 */
		 if &&classizz&i > &&min_classe&j and &&classizz&i <= &&max_classe&j then do;	/* 08.03.03.01 */
				 &&varcl&i = "&&min_cl&j < &&classizz&i <= &&max_cl&j";
				 &&varcl&i.._b = &&nome_cl&j;
				end;	/* 08.03.03.01 */
		%end;	/* 08.03.03 */
  %end;	/* 08.03 */
 run;

 %nonormali:

 %if %symexist(num_condiz) or num_condiz ^= 0 %then %do;	/* 08.04 */
  data &in._pt;
  set &in._pt;
  format &&varcl&i $&ludecla..;
  format &&varcl&i.._b 10.;
  if &&varcl&i = '' then &&varcl&i = '0';
  if &&varcl&i.._b = . then &&varcl&i.._b = -1;
  %if &num_condiz > 0 %then %do;	/* 08.04.01 */
   %do j=1 %to &num_condiz ;	/* 08.04.01.01 */
    %if %upcase(&&v_condiz&j) = %upcase(&&classizz&i) %then %do;	/* 08.04.01.01.01 */
	 if &&condiz&j then do;	/* 08.04.01.01.01.01 */
		 &&varcl&i = "&&cl_condiz&j";
		 &&varcl&i.._b = -&j;
		end;	/* 08.04.01.01.01.01 */
	%end;	/* 08.04.01.01.01 */
    %end;	/* 08.04.01.01 */
   %end;	/* 08.04.01 */
  run;
 %end;	/* 08.04 */

%end;	/* 08 */



%if %sysfunc(exist(&in._pt_temp)) %then %do;	/* 09 */
  proc delete data=&in._pt_temp;
  run;
 %end;	/* 09 */

%if %sysfunc(exist(&in._pt_temp2)) %then %do;	/* 10 */
  proc delete data=&in._pt_temp2;
  run;
 %end;	/* 10 */

%if %sysfunc(exist(&in._pt_temp3)) %then %do;	/* 11 */
  proc delete data=&in._pt_temp3;
  run;
 %end;	/* 11 */


%noclassizz:

%let ludecla = 0;

proc sql noprint;
 select count(*) into :ludecla
 from &in._var
 where utilizzo in ('O' 'Q' 'X' 'C');
quit;

%let ludecla = &ludecla;

proc sql noprint;
 select name, utilizzo into :variab1 - :variab&ludecla, :utiliz1 - :utiliz&ludecla
 from &in._var
 where utilizzo in ('O' 'Q' 'X' 'C');
quit;

%do i=1 %to &ludecla;	/* 11b */
 %let variab&i = &&variab&i;
 %let utiliz&i = &&utiliz&i;

 %if "&&utiliz&i" = "X" or "&&utiliz&i" = "O" %then %do;	/* 11b.01 */
  proc sql noprint;
   select count(distinct CL_&&variab&i.._b) format=40.0 into :ludecla2
   from &in._pt;
  quit;
 %end;	/* 11b.01 */
 %else %do;	/* 11b.02 */
  proc sql noprint;
   select count(distinct &&variab&i) format=40.0 into :ludecla2
   from &in._pt;
  quit;
 %end;	/* 11b.02 */

 %let ludecla2 = &ludecla2;

 %if &ludecla2 <= 1 %then %do;	/* 11b.03 */
   data &in._var ;
   set &in._var ;
    if name = "&&variab&i" then utilizzo = 'N';
   run;

   proc printto log=&log_0; run;
    %put Variabile &&variab&i eliminata dalla lista delle potenziali (ha solo &ludecla2 modalita);
   proc printto log=&output_log; run;

   data &in._pt;
   set &in._pt;
    drop 
   %if "&&utiliz&i" = "X" or "&&utiliz&i" = "O" %then %do;	/* 11b.03.01 */
    CL_&&variab&i CL_&&variab&i.._b
   %end;	/* 11b.03.01 */
   %else %do;	/* 11b.03.02 */
    &&variab&i
   %end;	/* 11b.03.02 */
	;
   run;
  %end;	/* 11b.03 */
%end;	/* 11b */

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;


proc printto log=&log_0; run;

%put 06 - Analisi della correlazione (o indipendenza) fra le variabili;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

proc printto log=&output_log; run; 

data &in._var_b;
set &in._var;
 if utilizzo = 'Q' or utilizzo = 'O' or utilizzo = 'X';
run;

data _null_;
set &in._var_b end=fine;
 call symputx('varaltre'!!strip(_n_),name);
 call symputx('utilaltre'!!strip(_n_),utilizzo);
 if fine then call symputx('numvaraltre',(_n_));
run;


data &in._temp &in._corrp &in._corrs &in._corr2 &in._corr3 &in._corr3b;
set _NULL_;
run;

data &in._corr4;
set _NULL_;
 format v1 $50.;
 format v2 $50.;
 format corr best12.;
 format tipo_corr $1.;
 format ut_v1 $2.;
 format ut_v2 $2.;
 format corr2 best12.;
run;

%if %symexist(numvarcl) = 0 %then %let numvarcl = 0;
%if %symexist(numvaraltre) = 0 %then %let numvaraltre = 0;


proc sql noprint;
 select count(*) into :num_corr
 from &in._var_b;
quit;

%if &num_corr < 2 %then %do;	/* 11b */
  proc delete data=&in._var_b ;
  run;

  %goto passo1;
 %end;	/* 11b */

proc delete data=&in._var_b ;
run;


data &in._pt_temp;
set &in._pt;
 keep 
%do i=1 %to &numvaraltre;	/* 12 */
    &&varaltre&i
 %end;	/* 12 */
  ;
run;

proc corr data=&in._pt_temp outp=&in._corrp outs=&in._corrs noprint;
run;

data &in._corrp ;
set &in._corrp ;
 if _TYPE_ = 'CORR';
 drop _TYPE_;
run;

data &in._corrs ;
set &in._corrs ;
 if _TYPE_ = 'CORR';
 drop _TYPE_;
run;


data &in._corr2;
set _NULL_;
 format v1 $50.;
 format v2 $50.;
 format corr best12.;
 format tipo_corr $1.;
run;


proc sql noprint;
select count(*) into :num_corr
 from &in._corrp;

select _NAME_ into :n_corr1 - :n_corr%trim(&num_corr)
 from &in._corrp;
quit;


%if %symexist(num_corr) %then %do;	/* 14 */
 %if &num_corr > 1 %then %do;	/* 14.01 */

  proc sql noprint;
%do i=1 %to &num_corr;	/* 14.01.01 */
 %do j=&i+1 %to &num_corr;	/* 14.01.01.01 */
   insert into &in._corr2
    select "&&n_corr&i", "&&n_corr&j", &&n_corr&j, "P"
	from &in._corrp
	where _NAME_ = "&&n_corr&i";

   insert into &in._corr2
    select "&&n_corr&i", "&&n_corr&j", &&n_corr&j, "S"
	from &in._corrs
	where _NAME_ = "&&n_corr&i";
 %end;	/* 14.01.01.01 */
%end;	/* 14.01.01 */
 quit;

 %end;	/* 14.01 */
%end;	/* 14 */


data &in._temp;
set &in._var;
 if utilizzo = 'X' or utilizzo = 'Q' or utilizzo = 'O';
 keep name utilizzo;
run;


data &in._corr2;
set &in._corr2;
 v1 = upcase(v1);
 v2 = upcase(v2);
run;


proc sql noprint;
 create table &in._corr3 as
  select a.*, b.utilizzo as ut_v1
  from &in._corr2 a, &in._temp b
  where a.v1 = b.name;

 create table &in._corr3b as
  select a.*, b.utilizzo as ut_v2
  from &in._corr3 a, &in._temp b
  where a.v2 = b.name;
quit;


data &in._corr3b;
set &in._corr3b;
 if ut_v1 = 'O' or ut_v2 = 'O' then do;	/* 14b */
    if tipo_corr = 'P' then delete;
   end;	/* 14b */
  else if tipo_corr = 'S' then delete;
run;


data &in._corr3b;
set &in._corr3b;
 corr2=0;
 if corr < -&taglio_correlazione or corr > &taglio_correlazione then corr2=1;
run;


data &in._corr4;
set &in._corr3b;
 if ut_v1 = 'X' or ut_v1 = 'O' then v1 = 'CL_' || v1;
 if ut_v2 = 'X' or ut_v2 = 'O' then v2 = 'CL_' || v2;
run;


proc sql noprint;
 create table &in._esccon2 as
  select a.var1, a.var2, b.utilizzo as util1
  from &in._esccon a left join &in._var b on
	(a.var1 = b.name);
quit;


proc sql noprint;
 create table &in._esccon3 as
  select a.*, b.utilizzo as util2
  from &in._esccon2 a left join &in._var b on
	(a.var2 = b.name);
quit;


data &in._esccon2;
set &in._esccon3;
 format v1 $100.;
 format v2 $100.;
 if util1 in ('C' 'O' 'Q' 'X') and util2 in ('C' 'O' 'Q' 'X');
 if util1 in ('O' 'X') then v1 = 'CL_' || var1;
  else v1 = var1;
 if util2 in ('O' 'X') then v2 = 'CL_' || var2;
  else v2 = var2;
 corr = .;
 tipo_corr = 'E';
 ut_v1 = util1;
 ut_v2 = util2;
 corr2 = 1;
 keep v1 v2 corr tipo_corr ut_v1 ut_v2 corr2;
run;

data &in._corr4;
set &in._corr4 &in._esccon2;
run;

proc delete data=&in._esccon2 &in._esccon3;
run;


proc delete data = &in._temp &in._corrp &in._corrs &in._corr2 &in._corr3 &in._corr3b &in._pt_temp;
run;


%passo1:

%if &simpson = 1 %then %do;	/* 15a */

 data &in._var_b;
 set &in._var;
  if utilizzo = 'Q' or utilizzo = 'O' or utilizzo = 'X' or utilizzo = 'C';
 run;

 data _null_;
 set &in._var_b end=fine;
  call symputx('varaltc'!!strip(_n_), compress(name));
  call symputx('utilaltc'!!strip(_n_), compress(utilizzo));
  if fine then call symputx('numvaraltc',(_n_));
 run;

 %if %symexist(numvaraltc) = 0 %then %let numvaraltc = 0;

 %if &numvaraltc < 2 %then %do;	/* 15b */
   proc delete data=&in._var_b ;
   run;

   %goto passo2;
  %end;	/* 15b */

 proc delete data=&in._var_b ;
 run;

 %do i=1 %to &numvaraltc;	/* 16 */
  %if "&&utilaltc&i" = "C" %then %do;	/* 16.01 */
   %do j=1 %to &numvaraltc;	/* 16.01.01 */
    %if ("&&utilaltc&j" ^= "C" and &j < &i) or &j > &i %then %do;	/* 16.01.01.01 */
     %simpson_c(vara=&&varaltc&i, varb=&&varaltc&j,
		utia=&&utilaltc&i, utib=&&utilaltc&j,
		prefisso=&in, taglio=&taglio_correlazione);

     proc sql noprint;
      select val into :coor
      from &in._rit;
     quit;

     proc delete data=&in._rit;
     run;

     %if &coor ^= 0 %then %do;	/* 16.01.01.01.01 */
       %if "&&utilaltc&i" = "X" or "&&utilaltc&i" = "O" %then %do;	/* 16.01.01.01.01.01 */
         %let ivaraltc&i = CL_&&varaltc&i;
        %end;	/* 16.01.01.01.01.01 */
       %else %do;	/* 16.01.01.01.01.02 */
         %let ivaraltc&i = &&varaltc&i;
        %end;	/* 16.01.01.01.01.02 */

       %if "&&utilaltc&j" = "X" or "&&utilaltc&j" = "O" %then %do;	/* 16.01.01.01.01.03 */
         %let ivaraltc&j = CL_&&varaltc&j;
        %end;	/* 16.01.01.01.01.03 */
       %else %do;	/* 16.01.01.01.01.04 */
         %let ivaraltc&j = &&varaltc&j;
        %end;	/* 16.01.01.01.01.04 */

      proc sql noprint;
       insert into &in._corr4 values
	("&&ivaraltc&i", "&&ivaraltc&j", &coor, "C", "&&utilaltc&i", "&&utilaltc&j", 1);
      quit;
     %end;	/* 16.01.01.01.01 */
    %end;	/* 16.01.01.01 */
   %end;	/* 16.01.01 */
  %end;	/* 16.01 */
 %end;	/* 16 */
%end;	/* 15a */


%passo2:

data &in._tesec;
set &in._tesec;
 passoprec = ahora;
 ahora = datetime();
 delta = ahora - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
 delta2 = ahora - passoprec;
 deltagg2 = int(delta2/(60*60*24));
 deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
 deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
 deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
 deltadec2 = deltasec2 + (delta2 - int(delta2));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;

 select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
 from &in._tesec;
quit;

%let dg = &dg;	%let dg2 = &dg2;
%let do = &do;	%let do2 = &do2;
%let dm = &dm;	%let dm2 = &dm2;
%let ds = &ds;	%let ds2 = &ds2;
%let dd = &dd ;	%let dd2 = &dd2;

proc printto log=&log_0; run;

%put 07 - Inizio regressione;
%put Tempo trascorso:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&dd.s (&dm2.m:&dd2.s);
    %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

proc printto log=&output_log; run;

data &in._mod;
set _NULL_;
 format nome $50.;
 format utilizzo $1.;
run;

data &in._po;
set &in._var;
 format nome $50.;
 format po 1.;
 if utilizzo in ('X' 'Q' 'C' 'O');
 if utilizzo in ('X' 'O') then nome = cats('CL_', name);
  else nome = name;
 po = 1;
 keep nome utilizzo po;
run;


proc sql noprint;
 select name into :v_risp
  from &in._var
  where utilizzo = 'R';


 select count(*) into :nin
  from &in._po;

 select nome into :vin1 - :vin%trim(&nin)
  from &in._po;

 select utilizzo into :uin1 - :uin%trim(&nin)
  from &in._po;
quit;

%let nin = &nin;

ods listing close;
ods output ParameterEstimates=&in._mcorr ModelFit=&in._smcorr ConvergenceStatus=&in._cocorr;

proc genmod data=&in._pt descending NAMELEN=50;
 model &v_risp =  / dist = &distribuzione ;
 output out=&in._dcorr predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
run;

ods output close;
ods listing;

proc sql noprint;
 select status into :stcorr
 from &in._cocorr;
quit;

%let stcorr = &stcorr;

proc delete data=&in._cocorr;
run;

data &in._smcorr;
set &in._smcorr;
 format df 20.0;
run;

data &in._mcorr;
set &in._mcorr;
 format level1 $30.;
 format estimate 20.10;
 parameter = upcase(parameter);
run;

proc sql noprint;
 select count(*) into :n_param
  from &in._mcorr
  where df ^= 0;
quit;

data &in._smcorr;
set &in._smcorr;
 if _n_ = 5 then do;	/* 17 */
  output;
  criterion = 'AIC';
  value = (2 * &n_param) - 2 * value;
 end;	/* 17 */
 output;
run;


%let attivo = 0;
%let vold = ;
%let vcold = ;

%do %while(&attivo < 2);	/* 18 */

%let nuovo = 0;

 %do i=1 %to &nin;	/* 18.01 */

 %if &oncamm = 1 %then %do;	/* 18.01b */
  %if &i = 1 %then %do;	/* 18.01b.01 */
   %let pcamm = %eval(&pcamm + 1);
  %end;	/* 18.01b.01 */
  %if &pcamm <= &lcamm %then %do;	/* 18.01b.02 */
   %if "&&vin&i" ^= "&&camm&pcamm" %then %goto goloop;
  %end;	/* 18.01b.02 */
  %else %do;	/* 18.01b.03 */
   %let oncamm = 0;
  %end;	/* 18.01b.03 */
 %end;	/* 18.01b */

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;

 %put 07 (&i./&nin.) - Provo ad inserire la variabile &&vin&i (modello: &vold);
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 proc sort data=&in._pt;
  by &&vin&i;
 run;

 %if %upcase(&&uin&i) = X or %upcase(&&uin&i) = O %then %do;	/* 18.01.01 */

 data &in._k1;
 set &in._pt;
  if &&vin&i.._b >= 0;
  keep &&vin&i.._b;
 run;

 proc sort data=&in._k1 nodup;
  by &&vin&i.._b;
 run;

 proc sql noprint;
  select count(*) into :limite_giri_k
  from &in._k1;
 quit;

 data &in._k2;
 set &in._k1;
  classe_orig = &&vin&i.._b;
  classe_der = classe_orig;
  keep classe_orig classe_der;
 run;

 data &in._ptk;
 set &in._pt;
  &&vin&i.._c = &&vin&i.._b;
 run;

 ods listing close;
 ods output ParameterEstimates=&in._mbestk ModelFit=&in._smbestk ConvergenceStatus=&in._cobestk;

 proc genmod data=&in._ptk descending NAMELEN=50;
 class &vcold
  %if %upcase(&&uin&i) = C %then %do;	/* 18.01.01.01a */
	&&vin&i
   %end;	/* 18.01.01.01a */
  %if %upcase(&&uin&i) = X or %upcase(&&uin&i) = O %then %do;	/* 18.01.01.01b */
	&&vin&i.._c
   %end;	/* 18.01.01.01b */
 / missing ;
 model &v_risp = &vold &&vin&i.._c / dist = &distribuzione ;
 output out=&in._dbestk predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
 run;

 ods output close;
 ods listing;

 proc sql noprint;
  select status into :stbestk
  from &in._cobestk;
 quit;

 %let stbestk = &stbestk;

 proc delete data=&in._cobestk;
 run;

 data &in._smbestk;
 set &in._smbestk;
  format df 20.0;
 run;

 data &in._mbestk;
 set &in._mbestk;
  format level1 $30.;
  format estimate 20.10;
  parameter = upcase(parameter);
 run;

 proc sql noprint;
  select count(*) into :n_param
   from &in._mbestk
   where df ^= 0;
 quit;

 data &in._smbestk;
 set &in._smbestk;
 if _n_ = 5 then do;	/* 18.01.01.02 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.01.01.02 */
 output;
 run;

 proc sql noprint;
  select value format=40.20 into :aic_bestk
   from &in._smbestk
   where criterion = 'AIC';
 quit;

 %let aic_bestk = &aic_bestk;

 proc delete data=&in._k1;
 run;

 %let contatore = 1;
 %let limite_giri_k = %eval(&limite_giri_k*3);
 %let ok_k = 4;

 %iniziowhile:

 proc sql noprint;
  select count(distinct classe_der) into :nncc
  from &in._k2;
 quit;

 %let nncc = &nncc;

 proc sql noprint;
  select distinct classe_der into :cl_der1 - :cl_der&nncc
  from &in._k2;
 quit;

 %do j=2 %to &nncc;	/* 18.01.01.03 */

  %let j2 = %eval(&j - 1);

  data &in._k4;
  set &in._k2;
   if classe_der = &&cl_der&j then classe_der = &&cl_der&j2;
  run;

  proc sql noprint;
   create table &in._ptk as
    select a.*, b.classe_der as &&vin&i.._c
    from &in._pt a left join &in._k4 b on
	(a.&&vin&i.._b = b.classe_orig);
  quit;

  data &in._ptk;
  set &in._ptk;
   if &&vin&i.._c = . then &&vin&i.._c = &&vin&i.._b;
  run;

  ods listing close;
  ods output ParameterEstimates=&in._mnewk ModelFit=&in._smnewk ConvergenceStatus=&in._conewk;

  proc genmod data=&in._ptk descending NAMELEN=50;
  class &vcold
  %if %upcase(&&uin&i) = C %then %do;	/* 18.01.01.03.01a */
	&&vin&i
   %end;	/* 18.01.01.03.01a */
   %if %upcase(&&uin&i) = X or %upcase(&&uin&i) = O %then %do;	/* 18.01.01.03.01b */
	&&vin&i.._c
   %end;	/* 18.01.01.03.01b */
  / missing ;
  model &v_risp = &vold &&vin&i.._c / dist = &distribuzione ;
  output out=&in._dnewk predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
  run;

  ods output close;
  ods listing;

  proc sql noprint;
   select status into :stnewk
   from &in._conewk;
  quit;

  %let stnewk = &stnewk;

  proc delete data=&in._conewk;
  run;

  data &in._smnewk;
  set &in._smnewk;
   format df 20.0;
  run;

  data &in._mnewk;
  set &in._mnewk;
   format level1 $30.;
   format estimate 20.10;
   parameter = upcase(parameter);
  run;

  proc sql noprint;
   select count(*) into :n_param
    from &in._mnewk
    where df ^= 0;
  quit;

  data &in._smnewk;
  set &in._smnewk;
  if _n_ = 5 then do;	/* 18.01.01.03.02 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.01.01.03.02 */
  output;
  run;

  proc sql noprint;
   select value format=40.20 into :aic_newk
    from &in._smnewk
    where criterion = 'AIC';
  quit;

  %let aic_newk = &aic_newk;

  %if &stnewk = 0 %then %do;	/* 18.01.01.03.02b */
   %if &stbestk ^= 0 or %sysevalf(&aic_bestk > &aic_newk) %then %do;	/* 18.01.01.03.03 */

     %let stbestk = &stnewk;
     %let aic_bestk = &aic_newk;
     %let ok_k = 1;

     data &in._mbestk;
     set &in._mnewk;
     run;

     data &in._smbestk;
     set &in._smnewk;
     run;

     data &in._dbestk;
     set &in._dnewk;
     run;

     data &in._k4_ok;
     set &in._k4;
     run;

    %end;	/* 18.01.01.03.03 */
   %end;	/* 18.01.01.03.02b */
  %end;	/* 18.01.01.03 */

 %if &ok_k ^= 1 %then %do;	/* 18.01.01.04 */

   %let contatore = %eval(&contatore+1);
   %if &contatore >= 2 %then %goto finewhilek;
  %end;	/* 18.01.01.04 */

 %else %do;	/* 18.01.01.05 */
   data &in._k2;
   set &in._k4_ok;
   run;

   proc delete data=&in._k4_ok;
   run;

   %let contatore = 0;
  %end;	/* 18.01.01.05 */

 %let ok_k = 1;

 proc sql noprint;
  create table &in._kriass as
   select classe_der, min(classe_orig) as min, max(classe_orig) as max
   from &in._k2
   group by classe_der;
 quit;

 data &in._kriass2;
 set &in._kriass;
  if min ^= max;
 run;

 proc sql noprint;
  select count(*) into :nncc
  from &in._kriass2;
 quit;

 %let nncc = &nncc;

 proc sql noprint;
  select classe_der, min, max into :co1 - :co&nncc, :mi1 - :mi&nncc, :ma1 - :ma&nncc
  from &in._kriass2;
 quit;

 proc delete data=&in._kriass &in._kriass2;
 run;

 %do j=1 %to &nncc;	/* 18.01.01.06 */

  proc sql noprint;
   select min(classe_orig) into :nuova_classe_k
   from &in._k2
   where classe_der = &&co&j and classe_orig ^= &&mi&j;
  quit;

  data &in._k3;
  set &in._k2;
   if classe_der = &&co&j and classe_orig ^= &&mi&j then classe_der = &nuova_classe_k;
  run;

  proc sql noprint;
   create table &in._ptk as
    select a.*, b.classe_der as &&vin&i.._c
    from &in._pt a left join &in._k3 b on
	(a.&&vin&i.._b = b.classe_orig);
  quit;

  data &in._ptk;
  set &in._ptk;
   if &&vin&i.._c = . then &&vin&i.._c = &&vin&i.._b;
  run;

  ods listing close;
  ods output ParameterEstimates=&in._mnewk ModelFit=&in._smnewk ConvergenceStatus=&in._conewk;

  proc genmod data=&in._ptk descending NAMELEN=50;
  class &vcold
  %if %upcase(&&uin&i) = C %then %do;	/* 18.01.01.06.01a */
	&&vin&i
   %end;	/* 18.01.01.06.01a */
   %if %upcase(&&uin&i) = X or %upcase(&&uin&i) = O %then %do;	/* 18.01.01.06.01b */
	&&vin&i.._c
   %end;	/* 18.01.01.06.01b */
   / missing ;
  model &v_risp = &vold &&vin&i.._c / dist = &distribuzione ;
  output out=&in._dnewk predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
  run;

  ods output close;
  ods listing;

  proc sql noprint;
   select status into :stnewk
   from &in._conewk;
  quit;

  %let stnewk = &stnewk;

  proc delete data=&in._conewk;
  run;

  data &in._smnewk;
  set &in._smnewk;
   format df 20.0;
  run;

  data &in._mnewk;
  set &in._mnewk;
   format level1 $30.;
   format estimate 20.10;
   parameter = upcase(parameter);
  run;

  proc sql noprint;
   select count(*) into :n_param
    from &in._mnewk
    where df ^= 0;
  quit;

  data &in._smnewk;
  set &in._smnewk;
  if _n_ = 5 then do;	/* 18.01.01.06.02 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.01.01.06.02 */
  output;
  run;

  proc sql noprint;
   select value format=40.20 into :aic_newk
    from &in._smnewk
    where criterion = 'AIC';
  quit;

  %let aic_newk = &aic_newk;

  %if &stnewk = 0 %then %do;	/* 18.01.01.06.02b */
   %if &stbestk ^= 0 or %sysevalf(&aic_bestk > &aic_newk) %then %do;	/* 18.01.01.06.03 */

     %let stbestk = &stnewk;
     %let aic_bestk = &aic_newk;
     %let ok_k = 2;

     data &in._mbestk;
     set &in._mnewk;
     run;

     data &in._smbestk;
     set &in._smnewk;
     run;

     data &in._dbestk;
     set &in._dnewk;
     run;

     data &in._k4_ok;
     set &in._k3;
     run;

    %end;	/* 18.01.01.06.03 */
   %end;	/* 18.01.01.06.02b */

  data &in._k4;
  set &in._k2;
   if classe_orig = &&ma&j then classe_der = &&ma&j;
  run;

  proc sql noprint;
   create table &in._ptk as
    select a.*, b.classe_der as &&vin&i.._c
    from &in._pt a left join &in._k4 b on
	(a.&&vin&i.._b = b.classe_orig);
  quit;

  data &in._ptk;
  set &in._ptk;
   if &&vin&i.._c = . then &&vin&i.._c = &&vin&i.._b;
  run;

  ods listing close;
  ods output ParameterEstimates=&in._mnewk ModelFit=&in._smnewk ConvergenceStatus=&in._conewk;

  proc genmod data=&in._ptk descending NAMELEN=50;
  class &vcold
    %if %upcase(&&uin&i) = C %then %do;	/* 18.01.01.06.04a */
	&&vin&i
    %end;	/* 18.01.01.06.04a */
    %if %upcase(&&uin&i) = X or %upcase(&&uin&i) = O %then %do;	/* 18.01.01.06.04b */
	&&vin&i.._c
    %end;	/* 18.01.01.06.04b */
    / missing ;
  model &v_risp = &vold &&vin&i.._c / dist = &distribuzione ;
  output out=&in._dnewk predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
  run;

  ods output close;
  ods listing;

  proc sql noprint;
   select status into :stnewk
   from &in._conewk;
  quit;

  %let stnewk = &stnewk;

  proc delete data=&in._conewk;
  run;

  data &in._smnewk;
  set &in._smnewk;
   format df 20.0;
  run;

  data &in._mnewk;
  set &in._mnewk;
   format level1 $30.;
   format estimate 20.10;
   parameter = upcase(parameter);
  run;

  proc sql noprint;
   select count(*) into :n_param
    from &in._mnewk
    where df ^= 0;
  quit;

  data &in._smnewk;
  set &in._smnewk;
  if _n_ = 5 then do;	/* 18.01.01.06.05 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.01.01.06.05 */
  output;
  run;

  proc sql noprint;
   select value format=40.20 into :aic_newk
    from &in._smnewk
    where criterion = 'AIC';
  quit;

  %let aic_newk = &aic_newk;

  %if &stnewk = 0 %then %do;	/* 18.01.01.06.05b */
   %if &stbestk ^= 0 or %sysevalf(&aic_bestk > &aic_newk) %then %do;	/* 18.01.01.06.06 */

     %let stbestk = &stnewk;
     %let aic_bestk = &aic_newk;
     %let ok_k = 3;

     data &in._mbestk;
     set &in._mnewk;
     run;

     data &in._smbestk;
     set &in._smnewk;
     run;

     data &in._dbestk;
     set &in._dnewk;
     run;

     data &in._k4_ok;
     set &in._k4;
     run;
   %end;	/* 18.01.01.06.06 */
  %end;	/* 18.01.01.06.05b */
 %end;	/* 18.01.01.06 */


 %if &ok_k < 2 %then %do;	/* 18.01.01.07 */

   %let contatore = %eval(&contatore+1);
   %if &contatore >= 2 %then %goto finewhilek;

  %end;	/* 18.01.01.07 */
  %else %do;	/* 18.01.01.08 */
    %if &ok_k = 2 %then %do;	/* 18.01.01.08.01 */

      data &in._k2;
      set &in._k4_ok;
      run;

      proc delete data=&in._k4_ok;
      run;

     %end;	/* 18.01.01.08.01 */
     %else %do;	/* 18.01.01.08.02 */

       data &in._k2;
       set &in._k4_ok;
       run;

       proc delete data=&in._k4_ok;
       run;

      %end;	/* 18.01.01.08.02 */

    %let contatore = 0;
   %end;	/* 18.01.01.08 */

 %let ok_k = 4;

 %let limite_giri_k = %eval(&limite_giri_k-1);
 %if &limite_giri_k <= 0 %then %goto finewhilek;

 %goto iniziowhile;

 %finewhilek:

  %mod_b_meno_a(moda=&in._smbestk, modb=&in._smcorr, alpha=&alfa, prefisso=&in);

  proc sql noprint;
   select val into :meglio
    from &in._rit;
  quit;

  proc delete data=&in._rit;
  run;

  %if &stbestk ^= 0 %then %do;
    %let meglio = 0;
   %end;
  %if &stcorr ^= 0 and &stbestk = 0 %then %do;
    %let meglio = 1;
   %end;

  %if &meglio = 1 %then %do;	/* 18.01.01.09 */

   proc sql noprint;
    select value format=40.20 into :aic_new
     from &in._smbestk
     where criterion = 'AIC';
   quit;

  %let aic_new = &aic_new;

   %if &nuovo = 0 %then %do;	/* 18.01.01.09.01 */

    %let stbest = &stbestk;
    %let nuovo = 1;
    %let aic_best = &aic_new;
    %let v_inserita = &&vin&i;

    data &in._mbest;
    set &in._mbestk;
    run;

    data &in._smbest;
    set &in._smbestk;
    run;

    data &in._dbest;
    set &in._dbestk;
    run;

    %end;	/* 18.01.01.09.01 */

   %else %do;	/* 18.01.01.09.02 */

    %if %sysevalf(&aic_best > &aic_new) %then %do;	/* 18.01.01.09.02.01 */

     %let stbest = &stbestk;
     %let aic_best = &aic_new;
     %let v_inserita = &&vin&i;

     data &in._mbest;
     set &in._mbestk;
     run;

     data &in._smbest;
     set &in._smbestk;
     run;

     data &in._dbest;
     set &in._dbestk;
     run;

     %end;	/* 18.01.01.09.02.01 */

    %end;	/* 18.01.01.09.02 */

   %end;	/* 18.01.01.09 */

 %end;	/* 18.01.01 */

 %else %do;	/* 18.01.02 */

  ods listing close;
  ods output ParameterEstimates=&in._mnew ModelFit=&in._smnew ConvergenceStatus=&in._conew;

  proc genmod data=&in._pt descending NAMELEN=50;
  class &vcold
   %if %upcase(&&uin&i) = C or %upcase(&&uin&i) = X or
	%upcase(&&uin&i) = O %then %do;	/* 18.01.02.01 */
		&&vin&i
   %end;	/* 18.01.02.01 */
   / missing ;
  model &v_risp = &vold &&vin&i / dist = &distribuzione ;
  output out=&in._dnew predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
  run;

  ods output close;
  ods listing;

  proc sql noprint;
   select status into :stnew
   from &in._conew;
  quit;

  %let stnew = &stnew;

  proc delete data=&in._conew;
  run;

  data &in._smnew;
  set &in._smnew;
   format df 20.0;
  run;

  data &in._mnew;
  set &in._mnew;
   format level1 $30.;
   format estimate 20.10;
   parameter = upcase(parameter);
  run;

  proc sql noprint;
   select count(*) into :n_param
    from &in._mnew
    where df ^= 0;
  quit;

  data &in._smnew;
  set &in._smnew;
  if _n_ = 5 then do;	/* 18.01.02.02 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.01.02.02 */
  output;
  run;

  %mod_b_meno_a(moda=&in._smnew, modb=&in._smcorr, alpha=&alfa, prefisso=&in);

  proc sql noprint;
   select val into :meglio
    from &in._rit;
  quit;

  proc delete data=&in._rit;
  run;

  %if &stnew ^= 0 %then %do;
    %let meglio = 0;
   %end;
  %if &stcorr ^= 0 and &stnew = 0 %then %do;
    %let meglio = 1;
   %end;

  %if &meglio = 1 %then %do;	/* 18.01.02.03 */

   proc sql noprint;
    select value format=40.20 into :aic_new
     from &in._smnew
     where criterion = 'AIC';
   quit;

   %let aic_new = &aic_new;

   %if &nuovo = 0 %then %do;	/* 18.01.02.03.01 */

    %let stbest = &stnew;
    %let nuovo = 1;
    %let aic_best = &aic_new;
    %let v_inserita = &&vin&i;

    data &in._mbest;
    set &in._mnew;
    run;

    data &in._smbest;
    set &in._smnew;
    run;

    data &in._dbest;
    set &in._dnew;
    run;

    %end;	/* 18.01.02.03.01 */

   %else %do;	/* 18.01.02.03.02 */

    %if %sysevalf(&aic_best > &aic_new) %then %do;	/* 18.01.02.03.02.01 */

     %let stbest = &stnew;
     %let aic_best = &aic_new;
     %let v_inserita = &&vin&i;

     data &in._mbest;
     set &in._mnew;
     run;

     data &in._smbest;
     set &in._smnew;
     run;

     data &in._dbest;
     set &in._dnew;
     run;

     %end;	/* 18.01.02.03.02.01 */

    %end;	/* 18.01.02.03.02 */

   %end;	/* 18.01.02.03 */

  %end;	/* 18.01.02 */

 %goloop:

 %end;	/* 18.01 */


%if &nuovo = 0 %then %do;	/* 18.02 */
 %let attivo = %eval(&attivo + 1);

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;

 %put 08 - Nessuna variabile aggiunta al modello;
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 %if &attivo = 2 %then %goto finemegaciclo;
%end;	/* 18.02 */

%else %do;	/* 18.03 */
 %let attivo = 0;

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;

 %put 08 - Variabile &v_inserita aggiunta al modello;
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 proc sql noprint;
  insert into &in._mod
   select nome, utilizzo
   from &in._po
   where nome = "&v_inserita";
 quit;

 data &in._corr5;
 set &in._corr4;
 if v1 = "&v_inserita" or v2 = "&v_inserita";
 if corr2 ^= 0;
 if v1 = "&v_inserita" then var = v2;
 if v2 = "&v_inserita" then var = v1;
 keep var;
 run;

 proc sort data=&in._corr5 nodup;
  by var;
 run;

 proc sql noprint;
  insert into &in._corr5
	set var = "&v_inserita";

  create table &in._po2 as
   select a.*, b.var
   from &in._po a left join &in._corr5 b on
	(a.nome = b.var);
 quit;

 data &in._po;
 set &in._po2;
  if var ^= '' then po = 0;
 drop var;
 run;

 proc delete data=&in._po2 &in._corr5;
 run;


 proc sql noprint;
  select utilizzo into :uinno
   from &in._mod
   where nome = "&v_inserita";
 quit;


 %if %upcase(&uinno) = X or %upcase(&uinno) = O %then %do;	/* 18.03.01 */

  data &in._nuoco;
  set &in._dbest;
   keep &v_inserita._b
	&v_inserita
	&v_inserita._c;
  run;

  proc sort data=&in._nuoco nodup;
   by 	&v_inserita._b
	&v_inserita
	&v_inserita._c;
  run;

  proc sql noprint;
   create table &in._nuoco2 as
    select &v_inserita._c, min(&v_inserita._b) as minimo, max(&v_inserita._b) as massimo
    from &in._nuoco
    group by &v_inserita._c;
  quit;

  data &in._nuoco2;
  set &in._nuoco2;
   if minimo ^= massimo;
  run;

  %let nuori = 0;

  proc sql noprint;
   select count(*) into :nuori
   from &in._nuoco2;
  quit;

  %let nuori = &nuori;

  proc sql noprint;
   select &v_inserita._c, minimo, massimo into :nuov1 - :nuov&nuori, :nuomi1 - :nuomi&nuori, :nuoma1 - :nuoma&nuori
   from &in._nuoco2;
  quit;

  proc delete data=&in._nuoco2;

  %do j=1 %to &nuori;	/* 18.03.01.01 */
   proc sql noprint;
    select &v_inserita into :minni
    from &in._nuoco
    where &v_inserita._b = &&nuomi&j;

    select &v_inserita into :massi
    from &in._nuoco
    where &v_inserita._b = &&nuoma&j;
   quit;

   %let minni = &minni;
   %let massi = &massi;

   %if %upcase(&uinno) = X %then %do;	/* 18.03.01.01.01 */
      %let nucla&j = 
	%qscan(&minni, 1, ' <=> ') < %qscan(&minni, 2, ' <=> ') <= %qscan(&massi, 3, ' <=> ');
     %end;	/* 18.03.01.01.01 */
    %else %if %upcase(&uinno) = O %then %do;	/* 18.03.01.01.02 */
      %let nucla&j = &minni <= &v_inserita <= &massi;
     %end;	/* 18.03.01.01.02 */
  %end;	/* 18.03.01.01 */


  data &in._nuoco;
  set &in._nuoco;
   &v_inserita._d = &v_inserita;
   %do j=1 %to &nuori;	/* 18.03.01.02 */
    if &v_inserita._c = &&nuov&j then &v_inserita._d = "&&nucla&j";
   %end;	/* 18.03.01.02 */
  run;

  proc sql noprint;
   create table &in._ptk as
    select a.*, b.&v_inserita._c, b.&v_inserita._d
    from &in._pt a left join &in._nuoco b on
	(a.&v_inserita._b = b.&v_inserita._b);
  quit;

  data &in._pt;
  set &in._ptk;
  run;

  proc delete data=&in._ptk;
  run;

  data &in._nuoco;
  set &in._nuoco;
   format var $40.;
   var = "&v_inserita";
  run;

  %if %sysfunc(exist(&in._kvar)) = 0 %then %do;	/* 18.03.01.03 */

    data &in._kvar;
    set &in._nuoco;
     giro = 1;
     kvar = &v_inserita;
     kvar_b = &v_inserita._b;
     kvar_c = &v_inserita._c;
     kvar_d = &v_inserita._d;
     keep var giro kvar kvar_b kvar_c kvar_d;
    run;

   %end;	/* 18.03.01.03 */

   %else %do;	/* 18.03.01.04 */

     %let ggg = 0;

     proc sql noprint;
      select max(giro) into :ggg
      from &in._kvar;
     quit;

     data &in._nuoco2;
     set &in._nuoco;
      giro = sum(&ggg, 1);
      kvar = &v_inserita;
      kvar_b = &v_inserita._b;
      kvar_c = &v_inserita._c;
      kvar_d = &v_inserita._d;
      keep var giro kvar kvar_b kvar_c kvar_d;
     run;

     data &in._kvar;
     set &in._kvar &in._nuoco2;
     run;

     proc delete data=&in._nuoco2;
     run;

    %end;	/* 18.03.01.04 */

  %end;	/* 18.03.01 */

  %let stcorr = &stbest;

  data &in._mcorr;
  set &in._mbest;
  run;

  data &in._smcorr;
  set &in._smbest;
  run;

  data &in._dcorr;
  set &in._dbest;
  run;

  %let ggg = 0;
  %let noloop = ;

  proc sql noprint;
   select max(passo) into :ggg
   from &in._passi;

   select nome into :noloop separated by ' '
   from &in._mod
   order by nome;
  quit;

  %let noloop = &noloop;

  data &in._nnnnome;
   format modello &max_format..;
   modello = "&noloop";
    output;
  run;

  data &in._nnnnome;
  set &in._nnnnome;
   passo = sum(&ggg, 1);
  run;

  data &in._passi;
  set &in._passi &in._nnnnome;
  run;

  proc delete data=&in._nnnnome;
  run;

 %end;	/* 18.03 */


%let nuovo = 0;
%let nin = 0;

proc sql noprint;
 select count(*) into :nin
 from &in._mod;
quit;

%let nin = &nin;

proc sql noprint;
 select nome, utilizzo into :vin1 - :vin&nin, :uin1 - :uin&nin
 from &in._mod;
quit;


 %do i=1 %to &nin;	/* 18.04 */

  ods listing close;
  ods output ParameterEstimates=&in._mnew ModelFit=&in._smnew ConvergenceStatus=&in._conew;

  proc genmod data=&in._pt descending NAMELEN=50;
  class
   %do j=1 %to &nin;	/* 18.04.01 */
	%if &j ^= &i %then %do;	/* 18.04.01.01 */
          %if %upcase(&&uin&j) = C %then %do;	/* 18.04.01.01.01a */
		&&vin&j
           %end;	/* 18.04.01.01.01a */
	  %if %upcase(&&uin&j) = X or %upcase(&&uin&j) = O %then %do;	/* 18.04.01.01.01b */
		&&vin&j.._c
	   %end;	/* 18.04.01.01.01b */
	 %end;	/* 18.04.01.01 */
    %end;	/* 18.04.01 */
   / missing ;
  model &v_risp =
   %do j=1 %to &nin;	/* 18.04.02 */
	%if &j ^= &i %then %do;	/* 18.04.02.01 */
	  %if %upcase(&&uin&j) = X or %upcase(&&uin&j) = O %then %do;	/* 18.04.02.01.01 */
		&&vin&j.._c
	   %end;	/* 18.04.02.01.01 */
	  %else %do;
		&&vin&j
	   %end;
	 %end;	/* 18.04.02.01 */
    %end;	/* 18.04.02 */
	 / dist = &distribuzione ;
  output out=&in._dnew predicted=predetti stdreschi=residui lower=inf upper=sup xbeta=xbet;
  run;

  ods output close;
  ods listing;

  proc sql noprint;
   select status into :stnew
   from &in._conew;
  quit;

  %let stnew = &stnew;

  proc delete data=&in._conew;
  run;

  data &in._smnew;
  set &in._smnew;
   format df 20.0;
  run;

  data &in._mnew;
  set &in._mnew;
   format level1 $30.;
   format estimate 20.10;
   parameter = upcase(parameter);
  run;

  proc sql noprint;
   select count(*) into :n_param
    from &in._mnew
    where df ^= 0;
  quit;

  data &in._smnew;
  set &in._smnew;
  if _n_ = 5 then do;	/* 18.04.03 */
	 output;
	 criterion = 'AIC';
	 value = (2 * &n_param) - 2 * value;
	end;	/* 18.04.03 */
  output;
  run;

  %mod_b_meno_a(moda=&in._smcorr, modb=&in._smnew, alpha=&alfa, prefisso=&in);

  proc sql noprint;
   select val into :meglio
    from &in._rit;
  quit;

  proc delete data=&in._rit;
  run;

  %if &stnew ^= 0 %then %do;
    %let meglio = 0;
   %end;
  %if &stcorr ^= 0 and &stnew = 0 %then %do;
    %let meglio = 2;
   %end;

  %if &meglio = 2 %then %do;	/* 18.04.04 */

   proc sql noprint;
    select value format=40.20 into :aic_new
     from &in._smnew
     where criterion = 'AIC';
   quit;

   %let aic_new = &aic_new;

   %if &nuovo = 0 %then %do;	/* 18.04.04.01 */

    %let stbest = &stnew;
    %let nuovo = 1;
    %let aic_best = &aic_new;
    %let v_inserita = &&vin&i;

    data &in._mbest;
    set &in._mnew;
    run;

    data &in._smbest;
    set &in._smnew;
    run;

    data &in._dbest;
    set &in._dnew;
    run;

    %end;	/* 18.04.04.01 */

   %else %do;	/* 18.04.04.02 */

    %if %sysevalf(&aic_best > &aic_new) %then %do;	/* 18.04.04.02.01 */

     %let stbest = &stnew;
     %let aic_best = &aic_new;
     %let v_inserita = &&vin&i;

     data &in._mbest;
     set &in._mnew;
     run;

     data &in._smbest;
     set &in._smnew;
     run;

     data &in._dbest;
     set &in._dnew;
     run;

     %end;	/* 18.04.04.02.01 */

    %end;	/* 18.04.04.02 */

   %end;	/* 18.04.04 */

 %end;	/* 18.04 */

%if &nuovo = 0 %then %do;	/* 18.05 */
 %let attivo = %eval(&attivo + 1);

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;

 %put 10 - Nessuna variabile eliminata dal modello;
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 %if &attivo = 2 %then %goto finemegaciclo;
%end;	/* 18.05 */

%else %do;	/* 18.06 */
 %let attivo = 0;
 %let nuovo = 0;
 %let vin1 = 0;
 %let stcorr = &stbest;

 data &in._mcorr;
 set &in._mbest;
 run;

 data &in._smcorr;
 set &in._smbest;
 run;

 data &in._dcorr;
 set &in._dbest;
 run;


 data &in._mod;
 set &in._mod;
  if nome = "&v_inserita" then delete;
 run;

 %let ggg = 0;
 %let noloop = ;

 proc sql noprint;
  select max(passo) into :ggg
  from &in._passi;

  select nome into :noloop separated by ' '
  from &in._mod
  order by nome;
 quit;

 %let noloop = &noloop;

 data &in._nnnnome;
  format modello &max_format..;
  modello = "&noloop";
   output;
 run;

 data &in._nnnnome;
 set &in._nnnnome;
  passo = sum(&ggg, 1);
 run;

 data &in._passi;
 set &in._passi &in._nnnnome;
 run;

 proc delete data=&in._nnnnome;
 run;

 data &in._tesec;
 set &in._tesec;
  passoprec = ahora;
  ahora = datetime();
  delta = ahora - inizio;
  deltagg = int(delta/(60*60*24));
  deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
  deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
  deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
  deltadec = deltasec + (delta - int(delta));
  delta2 = ahora - passoprec;
  deltagg2 = int(delta2/(60*60*24));
  deltaore2 = int((delta2 - deltagg2*(60*60*24)) / (60*60));
  deltamin2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60)) / (60));
  deltasec2 = int((delta2 - deltagg2*(60*60*24) - deltaore2*(60*60) - deltamin2*60) / (1));
  deltadec2 = deltasec2 + (delta2 - int(delta2));
 run;

 proc sql noprint;
  select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
  from &in._tesec;

  select deltagg2, deltaore2, deltamin2, deltasec2, deltadec2 into :dg2, :do2, :dm2, :ds2, :dd2
  from &in._tesec;
 quit;

 %let dg = &dg;	%let dg2 = &dg2;
 %let do = &do;	%let do2 = &do2;
 %let dm = &dm;	%let dm2 = &dm2;
 %let ds = &ds;	%let ds2 = &ds2;
 %let dd = &dd ;%let dd2 = &dd2;

 proc printto log=&log_0; run;

 %put 10 - Variabile &v_inserita eliminata dal modello;
 %put Tempo trascorso:;
 %if &dg > 0 %then %do;
    %put &dg GG  &do.h:&dm.m:&dd.s (&dg2 GG  &do2.h:&dm2.m:&dd2.s);
   %end;
  %else %if &do > 0 %then %do;
     %put &do.h:&dm.m:&dd.s (&do2.h:&dm2.m:&dd2.s);
    %end;
   %else %if &dm > 0 %then %do;
      %put &dm.m:&dd.s (&dm2.m:&dd2.s);
     %end;
   %else %do;
      %put &dd.s (&dd2.s);
     %end;

 proc printto log=&output_log; run;

 proc sql noprint;
  select nome into :vin1 - :vin%eval(&nin-1)
  from &in._mod;
 quit;

 %if %symexist(vin1) = 0 or &vin1 = 0 %then %do;	/* 18.06.01 */
  data &in._po;
  set &in._po;
   po = 1;
  run;
 %end;	/* 18.06.01 */

 %else %do;	/* 18.06.02 */
  data &in._corr5;
  set &in._corr4;
   if v1 in (
	%do j=1 %to %eval(&nin-1);	/* 18.06.02.01 */
	 "&&vin&j"
	%end;	/* 18.06.02.01 */
	) or
     v2 in (
	%do j=1 %to %eval(&nin-1);	/* 18.06.02.02 */
	 "&&vin&j"
	%end;	/* 18.06.02.02 */
	);
   if corr2 ^= 0;
  keep v1 v2;
  run;

  data &in._corr6;
  set &in._corr5;
   var = v1;
  output;
   var = v2;
  output;
  keep var;
  run;

  proc sql noprint;
   %do j=1 %to %eval(&nin-1);	/* 18.06.02.03 */
    insert into &in._corr6 values ("&&vin&j");
   %end;	/* 18.06.02.03 */
  quit;

  proc sort data=&in._corr6 nodup;
   by var;
  run;

  proc sql noprint;
   create table &in._po2 as
    select a.*, b.var
    from &in._po a left join &in._corr6 b on
	(a.nome = b.var);
  quit;

  data &in._po;
  set &in._po2;
   if var ^= '' then po = 0;
    else po = 1;
  drop var;
  run;

  proc delete data=&in._corr5 &in._corr6 &in._po2;
  run;

 %end;	/* 18.06.02 */

 proc sql noprint;
  select utilizzo into :uinno
   from &in._po
   where nome = "&v_inserita";
 quit;

 %if %upcase(&uinno) = X or %upcase(&uinno) = O %then %do;	/* 18.06.03 */
  data &in._pt;
  set &in._pt;
   drop &v_inserita._c &v_inserita._d;
  run;
 %end;	/* 18.06.03 */

%end;	/* 18.06 */

%let vold_b = ;
%let vold_c = ;
%let vcold_b = ;
%let vcold_c = ;

proc sql noprint;
 select nome into :vold_b separated by ' '
 from &in._mod
 where utilizzo not in ('X' 'O');

 select compress(nome)||'_c' into :vold_c separated by ' '
 from &in._mod
 where utilizzo in ('X' 'O');

 select nome into :vcold_b separated by ' '
 from &in._mod
 where utilizzo in ('C');

 select compress(nome)||'_c' into :vcold_c separated by ' '
 from &in._mod
 where utilizzo in ('X' 'O');

 select count(*) into :nin
 from &in._po
 where po = 1;
quit;

%let vold = &vold_b &vold_c;
%let vcold = &vcold_b &vcold_c;

%let nin = &nin;

proc sql noprint;
 select nome, utilizzo into :vin1 - :vin&nin, :uin1 - :uin&nin
 from &in._po
 where po = 1;
quit;

%finemegaciclo:

 %if &max_g < -10 %then %do;	/* 18.07 */
 %end;	/* 18.07 */
 %else %do;	/* 18.08 */
  %let max_g = %eval(&max_g-1);

  %if max_g <= 0 %then %do;	/* 18.08.01 */
	 %let attivo = 2;
	%end;	/* 18.08.01 */
 %end;	/* 18.08 */

%end;	/* 18 */

%let vold_b = ;
%let vold_c = ;

proc sql noprint;
 select nome into :vold_b separated by ', '
 from &in._mod
 where utilizzo not in ('X' 'O');

 select compress(nome)||'_c' into :vold_c separated by ', '
 from &in._mod
 where utilizzo in ('X' 'O');
quit;

proc printto log=&log_0; run;
%put ;
%put 11 - Modello completo. Variabili inserite: ;
%put @@@ &vold_b , &vold_c @@@;
%if &stcorr ^= 0 %then %do;
  %put @@@ ATTENZIONE: SEMBRA NON ESSERCI CONVERGENZA DELL ALGORITMO PER IL MODELLO TROVATO @@@;
 %end;
%put  Tabelle di riferimento:;
%put   &in._cond (Condizioni imposte per le classi);
%put   &in._corr4 (Correlazioni tra le variabili);
%put   &in._dcorr (Dati e stime per il modello);
%put   &in._esccon (Correlazioni imposte tra le variabili);
%put   &in._kvar (Classi individuate per le variabili di modello);
%put   &in._mcorr (Stima dei parametri per il modello);
%put   &in._mod (variabili di modello);
%put   &in._passi (Descrizione flusso stepwise);
%put   &in._po (Elenco variabili potenziali);
%put   &in._pt (Dataset Post Trattamento);
%put   &in._smcorr (Valori riassuntivi per il modello);
%put   &in._var (Variabili nel dataset di input);
%put   &in._zgri (Stime dei parametri del modello);
proc printto log=&output_log; run;


data &in._tesec;
set &in._tesec;
 fine = datetime();
 delta = fine - inizio;
 deltagg = int(delta/(60*60*24));
 deltaore = int((delta - deltagg*(60*60*24)) / (60*60));
 deltamin = int((delta - deltagg*(60*60*24) - deltaore*(60*60)) / (60));
 deltasec = int((delta - deltagg*(60*60*24) - deltaore*(60*60) - deltamin*60) / (1));
 deltadec = deltasec + (delta - int(delta));
run;

proc sql noprint;
 select deltagg, deltaore, deltamin, deltasec, deltadec into :dg, :do, :dm, :ds, :dd
 from &in._tesec;
quit;

%let dg = &dg;
%let do = &do;
%let dm = &dm;
%let ds = &ds;
%let dd = &dd ;


proc delete data=&in._tesec; run;

%if %sysfunc(exist(&in._dbest)) ^= 0 %then %do;	/* 19 */
	 proc delete data=&in._dbest; run;
	%end;	/* 19 */
%if %sysfunc(exist(&in._dbestk)) ^= 0 %then %do;	/* 20 */
	 proc delete data=&in._dbestk; run;
	%end;	/* 20 */
%if %sysfunc(exist(&in._dnew)) ^= 0 %then %do;	/* 21 */
	 proc delete data=&in._dnew; run;
	%end;	/* 21 */
%if %sysfunc(exist(&in._dnewk)) ^= 0 %then %do;	/* 22 */
	 proc delete data=&in._dnewk; run;
	%end;	/* 22 */
%if %sysfunc(exist(&in._k2)) ^= 0 %then %do;	/* 23 */
	 proc delete data=&in._k2; run;
	%end;	/* 23 */
%if %sysfunc(exist(&in._k3)) ^= 0 %then %do;	/* 24 */
	 proc delete data=&in._k3; run;
	%end;	/* 24 */
%if %sysfunc(exist(&in._k4)) ^= 0 %then %do;	/* 25 */
	 proc delete data=&in._k4; run;
	%end;	/* 25 */
%if %sysfunc(exist(&in._mbest)) ^= 0 %then %do;	/* 26 */
	 proc delete data=&in._mbest; run;
	%end;	/* 26 */
%if %sysfunc(exist(&in._mbestk)) ^= 0 %then %do;	/* 27 */
	 proc delete data=&in._mbestk; run;
	%end;	/* 27 */
%if %sysfunc(exist(&in._mnew)) ^= 0 %then %do;	/* 28 */
	 proc delete data=&in._mnew; run;
	%end;	/* 28 */
%if %sysfunc(exist(&in._mnewk)) ^= 0 %then %do;	/* 29 */
	 proc delete data=&in._mnewk; run;
	%end;	/* 29 */
%if %sysfunc(exist(&in._nuoco)) ^= 0 %then %do;	/* 30 */
	 proc delete data=&in._nuoco; run;
	%end;	/* 30 */
%if %sysfunc(exist(&in._smbest)) ^= 0 %then %do;	/* 31 */
	 proc delete data=&in._smbest; run;
	%end;	/* 31 */
%if %sysfunc(exist(&in._smbestk)) ^= 0 %then %do;	/* 32 */
	 proc delete data=&in._smbestk; run;
	%end;	/* 32 */
%if %sysfunc(exist(&in._smbestk_dev)) ^= 0 %then %do;	/* 33 */
	 proc delete data=&in._smbestk_dev; run;
	%end;	/* 33 */
%if %sysfunc(exist(&in._smcorr_dev)) ^= 0 %then %do;	/* 34 */
	 proc delete data=&in._smcorr_dev; run;
	%end;	/* 34 */
%if %sysfunc(exist(&in._smnew)) ^= 0 %then %do;	/* 35 */
	 proc delete data=&in._smnew; run;
	%end;	/* 35 */
%if %sysfunc(exist(&in._smnew_dev)) ^= 0 %then %do;	/* 36 */
	 proc delete data=&in._smnew_dev; run;
	%end;	/* 36 */
%if %sysfunc(exist(&in._smnewk)) ^= 0 %then %do;	/* 37 */
	 proc delete data=&in._smnewk; run;
	%end;	/* 37 */
%if %sysfunc(exist(&in._ptk)) ^= 0 %then %do;	/* 38 */
	 proc delete data=&in._ptk; run;
	%end;	/* 38 */
%if %sysfunc(exist(&in._temp)) ^= 0 %then %do;	/* 38b */
	 proc delete data=&in._temp; run;
	%end;	/* 38b */
%if %sysfunc(exist(&in._corrp)) ^= 0 %then %do;	/* 38c */
	 proc delete data=&in._corrp; run;
	%end;	/* 38c */
%if %sysfunc(exist(&in._corrs)) ^= 0 %then %do;	/* 38d */
	 proc delete data=&in._corrs; run;
	%end;	/* 38d */
%if %sysfunc(exist(&in._corr2)) ^= 0 %then %do;	/* 38e */
	 proc delete data=&in._corr2; run;
	%end;	/* 38e */
%if %sysfunc(exist(&in._corr3)) ^= 0 %then %do;	/* 38f */
	 proc delete data=&in._corr3; run;
	%end;	/* 38f */
%if %sysfunc(exist(&in._corr3b)) ^= 0 %then %do;	/* 38g */
	 proc delete data=&in._corr3b; run;
	%end;	/* 38g */
%if %sysfunc(exist(&in._pt_temp)) ^= 0 %then %do;	/* 38h */
	 proc delete data=&in._pt_temp; run;
	%end;	/* 38h */

data &in._modk &in._modc;
set &in._mod;
 if utilizzo in ('O' 'X') then output &in._modk;
 if utilizzo in ('Q' 'C') then output &in._modc;
run;

data &in._modc;
set &in._modc;
 format condizione &max_format..;
 format kvar_d &max_format..;
 kvar_c = .;
 kvar_d = '';
 condizione = '';
run;

%if %sysfunc(exist(&in._kvar)) ^= 0 %then %do;	/* 39 */
 proc sql noprint;
  create table &in._um as
   select var, max(giro) as max_giro
   from &in._kvar
   group by var;
 quit;

 proc sql noprint;
  create table &in._umk as
   select a.nome, a.utilizzo, b.max_giro
   from &in._modk a join &in._um b on
	(a.nome = b.var);
 quit;

 proc sql noprint;
  create table &in._modk as
   select a.nome, a.utilizzo, b.kvar_c, b.kvar_d
   from &in._umk a join &in._kvar b on
	(a.nome = b.var and
	 a.max_giro = b.giro);
 quit;

 data &in._modk1 &in._modk2;
 set &in._modk;
  if kvar_c <= 0 then output &in._modk1;
  if kvar_c > 0 then output &in._modk2;
 run;

 proc sql noprint;
  create table &in._condu as
   select a.*, b.utilizzo
   from &in._cond a left join &in._var b on
	(a.variabile = b.name);
 quit;

 data &in._condu;
 set &in._condu;
  format nome $100.;
  if utilizzo in ('X' 'O') then nome = cats('CL_', variabile);
 run;

 proc sql noprint;
  create table &in._modk1c as
   select a.nome, a.utilizzo, a.kvar_c, a.kvar_d, b.condizione
   from &in._modk1 a join &in._condu b on
	(a.nome = b.nome and
	 a.kvar_d = b.classe);
 quit;

 data &in._modk2;
 set &in._modk2;
  condizione = kvar_d;
 run;

 data &in._pgrgl;
 set &in._modk1c &in._modc &in._modk2;
 run;

 proc delete data=&in._um &in._modk &in._modc &in._umk &in._modk1 &in._modk2 &in._modk1c &in._condu;
 run;
%end;	/* 39 */

%else %do;	/* 40 */
 data &in._pgrgl;
 set &in._modc;
 run;

 proc delete data=&in._modk &in._modc;
 run;
%end;	/* 40 */

proc sort data=&in._pgrgl nodup;
 by nome utilizzo kvar_c;
run;

data &in._pgrgl;
set &in._pgrgl;
 if utilizzo = 'O' or utilizzo = 'X' then nome = cats(nome, '_C');
 kvar_cc = put(kvar_c, 20.);
 kvar_cc = compress(kvar_cc);
run;

data &in._zgr0;
set &in._mcorr;
 if _N_ = 1;
 nome = parameter;
 kvar_d = '';
 condizione = '1';
 utilizzo = '';
 kvar_c = .;
 keep nome kvar_d estimate condizione df level1 utilizzo kvar_c;
run;

proc sql noprint;
 create table &in._zgr1 as
  select a.nome, b.level1, a.kvar_d, b.estimate, a.condizione, b.df, a.utilizzo, a.kvar_c
  from (select *
	from &in._pgrgl
	where utilizzo = 'O' or utilizzo = 'X') a left join &in._mcorr b on
		(a.nome = b.parameter and a.kvar_cc = b.level1);
quit;

proc sql noprint;
 create table &in._zgr2 as
  select a.nome, b.level1, a.kvar_d, b.estimate, a.condizione, b.df, a.utilizzo, a.kvar_c
  from (select *
	from &in._pgrgl
	where utilizzo = 'C') a left join &in._mcorr b on
		(a.nome = b.parameter);
quit;

proc sql noprint;
 create table &in._zgr3 as
  select a.nome, b.level1, a.kvar_d, b.estimate, a.condizione, b.df, a.utilizzo, a.kvar_c
  from (select *
	from &in._pgrgl
	where utilizzo = 'Q') a left join &in._mcorr b on
		(a.nome = b.parameter);
quit;


data &in._zgri;
set &in._zgr1 &in._zgr0 &in._zgr2 &in._zgr3;
run;


proc delete data=&in._zgr0 &in._zgr1 &in._zgr2 &in._zgr3 &in._pgrgl;
run;


proc sort data=&in._zgri nodup;
 by nome level1;
run;


proc sql noprint;
 create table &in._zgri2 as
  select a.*, b.type
  from &in._zgri a left join &in._var b on
  	(a.nome = b.name);
quit;

data &in._zgri;
set &in._zgri2;
 condizione = strip(condizione);
 if kvar_c >= 0 or kvar_c = . then do;	/* 40b */
  if utilizzo = 'X' then do;	/* 41 */
    mm = find(condizione, 'min <', 'i');
    if mm = 1 then do;	/* 41.01 */
      condizione = substr(condizione, mm + 6);
     end;	/* 41.01 */
    mm = find(condizione, ' max', 'i');
    if mm > 0 and (mm + 4 > length(condizione)) then do;	/* 41.02 */
      condizione = substr(condizione, 1, mm-4);
     end;	/* 41.02 */
   end;	/* 41 */
  if utilizzo = 'O' then do;	/* 42 */
    mm = find(condizione, '<=', 'i');
    if mm > 0 then do;	/* 42.02 */
      condizione = scan(condizione, 1, ' <=> ') || ' <= ' || compress(substr(scan(condizione, 2, ' <=> '), 4)) || ' <= ' || scan(condizione, 3, ' <=> ');
     end;	/* 42.02 */
    else do;	/* 42.03 */
      mm = length(nome);
      condizione = compress(substr(compress(nome), 4, mm-4-1)) || ' = ' || compress(kvar_d);
     end;	/* 42.03 */
   end;	/* 42 */
  if utilizzo = 'C' then do;	/* 43 */
    if type = 1 then condizione = compress(nome) || ' = ' || compress(level1);
    if type = 2 then condizione = compress(nome) || " = '" || compress(level1) || "'";
   end;	/* 43 */
  end;	/* 40b */
 if utilizzo = 'O' or utilizzo = 'X' then do;	/* 44 */
   mm = length(nome);
   nome = compress(substr(compress(nome), 4, mm-4-1));
  end;	/* 44 */
 drop type mm kvar_c;
run;

proc delete data=&in._zgri2;
run;

data &in._vak;
set &in._var;
 if utilizzo = 'K';
 name = 'K_' || compress(name);
 name = compress(name);
run;

proc sql noprint;
 select count(*) into :nukero
 from &in._vak;
quit;

%let nukero = &nukero;

%if &nukero <= 0 %then %do;	/* 45 */
  %goto finerik;
 %end;	/* 45 */

proc sql noprint;
 create table &in._vak2 as
  select a.type, b.*
  from &in._vak a inner join &in._zgri b on
	(a.name = b.nome);
quit;

proc sql noprint;
 select count(distinct nome) into :nukero
 from &in._vak2;
quit;

%let nukero = &nukero;

%if &nukero <= 0 %then %do;	/* 46 */
  proc delete data=&in._vak2;
  run;

  %goto finerik;
 %end;	/* 46 */

proc sql noprint;
 select distinct nome into :ku1 - :ku&nukero
 from &in._vak2;
quit;

%do j=1 %to &nukero;	/* 47 */

 %let ku&j = &&ku&j;

 data &in._vak3;
 set &in._vak2;
  if nome = "&&ku&j";
  nome_old = substr(nome, 3);
 run;

 proc sort data=&in._vak3;
  by descending level1;
 run;

 proc sql noprint;
  select count(*) into :nuker
  from &in._vak3;
 quit;

 %let nuker = &nuker;

 proc sql noprint;
  select type, level1, estimate, condizione, df, nome_old into
	:ktype1 - :ktype&nuker, :klev1 - :klev&nuker, :kest1 - :kest&nuker,
	:kcondi1 - :kcondi&nuker, :kdf1 - :kdf&nuker, :kuo1 - :kuo&nuker
  from &in._vak3;
 quit;

 data &in._kcl2;
 set &in._kcl;
  if compress('K_' || compress(var_orig)) = "&&ku&j";
  &&ku&j = cl_nuova;
 run;

 data &in._kcl2;
 set &in._kcl2;
  format level1 $30.;
  %do jj=1 %to &nuker;	/* 47.01 */
   if &&kcondi&jj then do;	/* 47.02 */
    level1 = compress("&&klev&jj");
   end;	/* 47.02 */
  %end;	/* 47.01 */
 run;

 %do jj=1 %to &nuker;	/* 47.03 */
  %let ktype&jj = &&ktype&jj;
  %let klev&jj = &&klev&jj;
  %let kest&jj = &&kest&jj;
  %let kcondi&jj = &&kcondi&jj;
  %let kdf&jj = &&kdf&jj;
  %let kuo&jj = &&kuo&jj;

  %if &&ktype&jj = 1 %then %do;	/* 47.03.01 */

   proc sql noprint;
    select cl_orig into :k2cond&jj separated by ', '
    from &in._kcl2
    where compress(level1) = compress("&&klev&jj");
   quit;

  %end;	/* 47.03.01 */

  %else %if &&ktype&jj = 2 %then %do;	/* 47.03.02 */

   proc sql noprint;
    select "'" || compress(cl_orig) || "'" into :k2cond&jj separated by ', '
    from &in._kcl2
    where compress(level1) = compress("&&klev&jj");
   quit;

  %end;	/* 47.03.02 */

  %let k2cond&jj = &&kuo&jj in ( &&k2cond&jj );

 %end;	/* 47.03 */

 data &in._zgri;
 set &in._zgri;
  if compress(nome) ^= compress("&&ku&j");
 run;

 proc sql noprint;
  %do jj=1 %to &nuker;	/* 47.04 */
   insert into &in._zgri values ("&&kuo&jj", "&&klev&jj", "", &&kest&jj, "&&k2cond&jj", &&kdf&jj, "K");
  %end;	/* 47.04 */
 quit;

 proc delete data=&in._vak3 &in._kcl2;
 run;

%end;	/* 47 */

proc delete data=&in._vak2;
run;

%finerik:

proc delete data=&in._vak;
run;

proc sort data=&in._zgri;
 by nome descending level1;
run;

%theend:

proc printto log=&log_0; run;

%put Tempo di esecuzione totale:;
%if &dg > 0 %then %do;
   %put &dg GG  &do.h:&dm.m:&ds.s.&dd ;
  %end;
 %else %if &do > 0 %then %do;
    %put &do.h:&dm.m:&ds.s.&dd ;
   %end;
  %else %if &dm > 0 %then %do;
     %put &dm.m:&ds.s.&dd ;
    %end;
   %else %do;
      %put &dd.s;
     %end;

%put &versione_dr;

proc printto log=log; run;

%mend classizz;






  Main index     Programs index     Autoreg index  
Vai alla versione Italiana

Creation date: 17 Sep 2010
Translation date: 30 Dec 2012
Last change: 28 Jul 2013

Translation reviewed by Giulia Di Lallo