/* TEMA 6 CREACION DE VARIABLES y USO FUNCIONES DE SAS (e.g. SUM,..)*/

libname W 'C:\Users\daniel.fernandez\Dropbox\02.Teaching\04.UB-UPC\CompEstad_Optim\02.Practiques\01.Future\S06\dades_s06';

OPTIONS FMTSEARCH=(W);


/*options nofmterr;
proc format;
value cancel 1 = 'Si' 2 = 'No';
value changes 0 = 'No Respon'
              1 = 'No'
			  2 = 'Si.Compra 1 v/mes'
			  3 = 'Si.Compra 2 v/mes'
			  4 = 'Si.Compra 1 v/setmana'
			  5 = 'Si.Compra ocas.'
			  6 = 'Si. Deixarà de comprar';
value contact 1 = 'Si' 2 = 'No';
value dept 1 = 'Coses per la llar'
           2 = 'Roba'
		   3 = 'Electrònica'
		   4 = 'Articles Esportius';
value gender 1 = 'Home'
             2 = 'Dona';
value length 1 = '3 mesos o menys'
             2 = '4-6 mesos'
			 3 = '6-12 mesos'
			 4 = '1-2 anys'
			 5 = '2-3 anys'
			 6 = '3-4 anys'
			 7 = '4-5 anys'
			 8 = '5 anys o més';
value motiv 0 = 'No respon'
            1 = 'Preus massa elevats'
			2 = 'Mal servei'
			3 = 'Altres';
value reason 0 = 'No respon'
             1 = 'Prop de la feina'
			 2 = 'Prop de casa';
value recomen 1 = 'Amb tota seguretat'
              2 = 'Molt probable'
			  3 = 'Possiblement'
			  4 = 'Probablement no'
			  5 = 'Segur que no'
			  6 = 'No ho sap';
value satmega 0 = 'No respon'
              1 = 'Satisfet'
			  2 = 'No satisfet';
value store 1 = 'Valencia'
            2 = 'Barcelona'
			3 = 'Madrid'
			4 = 'Vigo'
			5 = 'Sevilla'; 
run; */


DATA MEGAZ;
SET W.MEGAZ;
  vsum1=v1+v2+v3+v4+v5+v6;
  vsum2=sum(of v1 -- v6);
  varit=exp(abs(v1-v2)); /*cualquier operacion que queramos*/
  vmean=mean(of v1 -- v6); /*media*/
  vstd=std(of v1 -- v6); /*dev estandar*/
  vvar=var(of v1 -- v6); /*varianza*/
  vmean_i=int(vmean); /*devuelve la parte entera*/
  vmiss=nmiss(of v1 -- v6); /*cuenta el numero de missings*/
RUN;

/*TRANSFORMACION CONDICIONAL DE VARIABLES*/

data megaz;
set megaz;
if (gender=1 & age < 35) then var1 = 1; 
run;
/* Aparace missing en los casos que no se cumple (gender=1 & age < 35)  */

data megaz;
set megaz;
if (gender=1 & age < 35) then var2 = 1;
else var2=2;
run;

proc freq data = megaz; tables var1 / missing; run;
proc freq data = megaz; tables var2 / missing; run;
proc freq data = megaz; tables var1*var2 / missing; run;


/* 3 formas de escribir lo mismo */
data megaz;
set megaz;
if (gender=1 & age < 35) then var3 = 1;
if (gender=1 & age >= 35) then var3 = 2;
if (gender=2) then var3 = 3;
run;

data megaz;
set megaz;
if (gender=1 & age < 35) then var4 = 1;
else if (gender=1 & age >= 35) then var4 = 2;
else var4 = 3;
run;

data megaz;
set megaz;
var5 = (gender=1 & age < 35)*1 + (gender=1 & age >= 35)*2 + (gender = 2)*3;
run;

proc freq data = megaz; tables var3*var4*var5; run;

/*creación de más de una variable con un mismo bloque if: Usar DO ... END;*/

data megaz;
set megaz;
if (gender=1 & age < 35) then do;
    var6 = 1; 
    var7=sum(of v1 -- v6);
    var8=mean(of v1 -- v6);
    var9=std(of v1 -- v6);
end;
run;


/*SELECCION DE OBSERVACIONES*/

data megaz2;
set megaz;
if (gender=1 & age < 35);
run;


/*CREACION DE VARIABLES A TRAVES DE ARRAYS*/

/* Array - Defines the elements of an array */


proc freq data=megaz; tables v1-v6; run;



DATA MEGAZ (DROP = i);
SET MEGAZ;
ARRAY VAL(6) V1 - V6; /* Asignamos los valores de las vars V1-V6 a cada una de las 6 
posiciones del array VAL */
ARRAY XX(6) X1 - X6; /* Podemos tambien asignar variables no inicializadas, que
seran las variables nuevas que crearemos */
DO i = 1 TO 6;
   IF (VAL(i)>=5) THEN XX(i)=1;
   ELSE IF (VAL(i)>=0) THEN XX(i)=0;
   ELSE XX(i)=.;
END;
RUN;

proc print data=megaz; var v1-v6 x1-x6;
run;


/*ARRAYS CON DIMENSION VARIABLE: X(*)*/


data mis1;
input x1 x2 x3 x4 $;
datalines;
1 -99 2 -99
-99 3 -99 06
0 -99 2 -99
;
run;  /* missings como -99*/
proc print; run;

data mis2 (drop = i);
set mis1;
 /*todas las numericas de mi base
    tiene los missings como -99*/
ARRAY X(*) _numeric_; /* _numeric_ indica que todas las variables numericas serán utilizadas 
como elementos del array. Ponemos X(*) porque no sabemos cuantas variables numéricas habrá y 
queremos que SAS cuente el número de elementos por nosotros */ 
   DO i = 1 TO dim(X); /* la función dim devuelve el numero of elements del array */
   IF X(i) = -99 THEN X(i) =.;
END;
run;

proc print; run;


/* Otro ejemplo */
data mis3;
input x1 x2 x3 x4 $ x5 $;
datalines;
1 -99 2 p 07
-99 3 -99 06 p
0 -99 2 p p
;
run;
proc print; run;

data mis4 (drop = i);
set mis3;
 /*Igual que antes pero ahora busca solo en las cadena */
ARRAY X(*) _character_; /* las buscará por nosotros*/
   DO i = 1 TO dim(x);
   IF X(i) = "p" THEN X(i) =' ';
  END;
run;

proc print; run;

data mis5;
input x1 x2 x3 x4;
datalines;
1 -99 2 -99
-99 3 -99 6
0 -99 2 -99
;
run;
proc print; run;

data mis6 (drop = i);
set mis5;
/*cuando sabemos que todas las variables en la base de datos son del mismo tipo, 
entonces no hace falta poner _numeric_ or _character_, con _all_ es suficiente.
En nuestro caso todas son numéricas*/
ARRAY X(*) _all_; /* * el contará por nosotros*/
   DO i = 1 TO dim(x);
   IF X(i) = -99 THEN X(i) =.;
  END;
run;

proc print; run;


/*DEFINICIÓN DE VALORES MISSING DE USUARIO*/

DATA EJEM1;
INPUT X1 X2 X3;
DATALINES;
1 2 99999
3 4 7
5 1 99999
2 3 8
2 . 7
3 4 3
3 7 7
; 
RUN;

PROC MEANS DATA=EJEM1; RUN; /* X3 tiene missings. Mirad media y maximo de X3 */

DATA EJEM1; 
SET EJEM1; 
IF X3=99999 THEN X3=.; /*Cambiamos el valor del missing por el missing del sistema . PUNTO*/
RUN;
/* Así SAS lo reconoce como missing y no lo tiene en cuenta en el cálculo de la media.
Mirad el número de observaciones N en X3 ahora */

PROC MEANS DATA=EJEM1; RUN;

/* Volvemos a poner los missings como antes 99999 */
DATA EJEM1;
INPUT X1 X2 X3;
DATALINES;
1 2 99999
3 4 7
5 1 99999
2 3 8
2 . 7
3 4 3
3 7 7
; 
RUN;
/* Ahora vamos a definir nosotros nuestro propio missing, en lugar de . usaremos A */
DATA EJEM1; 
SET EJEM1; 
IF X3=99999 THEN X3=.A; /*Cuando ponemos '.A' significa que el valor A 
será missing y lo hemos definido nosotros (el usuario)*/
RUN;

PROC MEANS DATA=EJEM1; RUN; /* Resultados buenos como antes, mirad N */

/*DEFINIR EL MISSING DE USUARIO DENTRO DEL BLOQUE DATA*/

DATA EJEM1;
INPUT X1 X2 X3;
DATALINES;
1 2 .A
3 4 7
5 1 .A
2 3 8
2 . 7
3 4 3
3 7 7
; 
RUN;

PROC MEANS DATA=EJEM1; RUN; /* Resultados buenos como antes, mirad N */

/* Otra forma */
DATA EJEM1;
INPUT X1 X2 X3;
missing A;
DATALINES;
1 2 A
3 4 7
5 1 A
2 3 8
2 . 7
3 4 3
3 7 7
; 
RUN;

PROC MEANS DATA=EJEM1; RUN; /* Resultados buenos como antes, mirad N */

/*GENERACION DE BASES DE DATOS POR SIMULACION*/

/*podéis hacerlo con las funciones RANnnn(seed), las más utilizadas son:

RANBIN(SEED,N,P) generates a number from an binomial distribution with parameters N,P
RANEXP(SEED): generates a number from an exponential distribution with parameter 1
 ranexp(seed)/lambda: generates a number from an exponential distribution with parameter lambda
RANGAM(SEED,ALPHA): generates a number from a gamma distribution with parameter a
 x=beta*rangam(seed,alpha): shape parameter ALPHA and scale BETA 
RANNOR(SEED): normal(0,1)
 x=MU+sqrt(S2)*rannor(seed); normal(mu,s2)
RANPOI(SEED,M): Poisson(m)
RANUNI(SEED): uniform distribution on the interval (0,1)
 a*ranuni(seed)+b: uniform distribution on the interval (a,a+b)
    */

DATA u1 (drop = i);
  do i = 1 to 100;
    x=rannor(635985);
    output;
  end;
run;

proc print data= u1;run;
proc univariate data=u1;
var x;
histogram;
run;

/*también puede hacerse con una rutina CALL, las más utilizadas

  CALL RANBIN(SEED,N,P,X)
  CALL RANEXP(SEED,X)
  CALL RANGAM(SEED,ALPHA,X)
  CALL RANNOR(SEED,X)
  CALL RANPOI(SEED,M,X)
  CALL RANUNI(SEED,X)

The parameter X is tha variable where we store the variate produced

*/

data u2(keep = x);
   seed = 898647;
   do i = 1 to 100;
	  call ranuni(seed, x); 
      output;
   end;
run;
proc print data= u2;
run;
proc univariate data=u2;
var x;
histogram;
run;



/*FUNCIONES FECHA*/

DATA MEGAZ;
SET MEGAZ;
DIA=CEIL(28*RANUNI(346895)); /*escoger aleatoriamente un dia entre 1 y 28 */
MES=CEIL(12*RANUNI(859647)); /*escoger aleotoriamente un mes */
ANY=2013;
DATAE=MDY(MES,DIA,ANY);
FORMAT DATAE DDMMYY10.;
RUN;

proc print; var dia mes any datae; run;

/*CREA AHORA UNA VARIABLE SS1 QUE VALGA 1 SI LA ENTREVISTA SE HIZO EN FEBRERO 
Y 0 EN CASO CONTRARIO, 
UTILIZANDO UNICAMENTE LA VARIABLE DATAE*/

DATA MEGAZ;
SET MEGAZ;
IF MONTH(DATAE)=2 THEN SS1=1;
ELSE SS1=0;
RUN;

proc print; var dia mes any datae ss1; run;

/*FUNCIONES CADENA:

CAT(CHAR1,CHAR2,..): CONCATENA
LOWCASE(CHAR): PASA A MINÚSCULAS
UPCASE(CHAR): PARA A MAYÚSCULAS
SUBSTR(CHAR,START,LENGTH): EXTRAE UNA CADENA de CHAR desde la posición START 
							y LENGTH posiciones
*/

DATA EJEM2;
INPUT ID $ PROV $;
DATALINES;
12457856 bcn
98653255 gir
78569595 tar
45659811 lle
98685735 bcn
78784585 tar
65962684 tar
98659912 gir
; 
RUN;

DATA EJEM2;
SET EJEM2;
CODI1=cat(ID,PROV);
CODI2=cat(ID,UPCASE(PROV));
CODI3=SUBSTR(ID,3,2);
RUN;

proc print; run;



/* CONVERSIÓN DE VARIABLES CADENA A NUMÉRICAS O FECHA, Y VICEVERSA */

data char;
input string $8. date $6. numer fecha ddmmyy8.; /* variable carácter  -  variable fecha  -  variable numerica */
 numeric=input(string,8.); /* Convertir carácter a numérica: 
                              8. es el formato que va a leer (caracter), en este caso:
 								primeros 8 caracteres como número. 
 								Y si hay decimales los trata con . */
 numeric2=string+0;        /* Convertir carácter a numérica: si sólo contiene números 
                              la carácter pasa a numérica mediante 
 							  cualquier operación aritmética  */
 chara=put(numer,5.);     /* Convertir numérica a carácter  */
 sasdate=input(date,mmddyy6.);  /* Convertir carácter a fecha */
 fechcar=put(fecha,ddmmyy8.);  /* Convertir carácter a fecha */
 format sasdate ddmmyy10. chara $5. fecha ddmmyy8.; 
datalines;
1234.56 031704 121.2 12/11/15
3920    123104 132.2 20/11/25
;

proc contents varnum;
run;

proc print; 
run; 
