A continuación os planteo un monográfico más orientado a principiantes con SAS. Vamos a realizar un acercamiento a los conjuntos de datos SAS agrupados por variables. La premisa fundamental es: un conjunto de datos SAS está agrupado por una variable si está ordenado por ella. Para ordenar variables empleamos el PROC SORT:
PROC SORT DATA=
BY (DESCENDING)
RUN;
Repetimos un conjunto de datos SAS puede agruparse por una o varias variables si está ordenado por ellas. Algunas de las posibilidades que nos ofrecen este tipo de conjuntos de datos son:
• Buscar máximos y mínimos por grupos
• Crear ranking por grupos
• Realizar sumarizaciones
• Unir conjuntos de datos
Para ilustrar esto ejemplos vamos a emplear un conjunto de datos SAS de la librería SASHELP llamado SHOES que todos tenemos en nuestra sesión y que contiene las siguientes variables:
# Variable
1 Region
2 Product
3 Subsidiary
4 Stores
5 Sales
6 Inventory
7 Returns
La primera tarea encomendada es encontrar el mínimo y el máximo número de tiendas por producto en el total de las regiones:
data ejemplo;
set sashelp.shoes;
proc sort data=ejemplo; by product stores; quit;
proc freq; tables product; quit;
Trabajamos con una copia del dataset de SASHELP y lo primero es realizar la ordenación por la variable que nos agrupa nuestra tabla y después por la variable que deseamos estudiar. Con FREQ realizamos una tabla de frecuencias y observamos que tenemos 8 grupos, 8 tipos de productos. Una vez realizada la ordenación a la hora de leer el dataset hemos de emplear la instrucción BY:
data minimos_maximos;
set ejemplo;
by product;
if first.product then minimo=stores;
if last.product then maximo=stores;
if minimo ne . or maximo ne .; drop stores--Returns;
run;
proc print; quit;
Al emplear la instrucción BY disponemos de dos nuevas variables de sistema que sólo aparecen durante la ejecución del paso data: FIRST.
Otra de las tareas habituales con conjuntos de datos agrupados es la realización de ranking por grupo. Si, por ejemplo, deseamos realizar un ranking de ventas por región tendremos que hacer:
proc sort data=ejemplo; by region sales; quit;
data ranking;
set ejemplo;
by region;
retain posicion ;
if first.region then posicion=1;
else posicion=posicion+1;
run;
Lo primero es ordenar por región y descendentemente por ventas. En este ejemplo empleamos una nueva instrucción RETAIN
Si deseamos crear sumarizaciones la metodología será igual que la anterior:
proc sort data=ejemplo; by region sales; quit;
data suma_region;
set ejemplo;
by region;
retain total_ventas;
if first.region then total_ventas=sales;
else total_ventas=sum(total_ventas,sales);
if last.region then output;
keep region total_ventas;
run;
La unión de conjuntos de datos SAS tendremos que analizarla en capítulos posteriores, pero es imprescindible recordar que, para unir conjuntos de datos SAS éstos han de estar agrupados por la variable que realiza la unión. Como siempre si tenéis cualquier duda, sugerencia o trabajo a tiempo parcial que me permita jugar más tiempo con mis hijos podéis contactar conmigo en rvaquerizo@analisisydecsision.es
IdClient IdArtic Fecha Secuencia
1 23 01/01/2010 1
1 24 01/01/2010 1
1 45 05/01/2010 2
1 67 05/01/2010 2
1 56 20/01/2010 3
1 89 20/01/2010 3
1 90 20/01/2010 3
2 67 01/01/2010 1
2 6 01/01/2010 1
2 7 08/01/2010 2
2 45 08/01/2010 2
2 23 08/01/2010 2
A través de la tabla idcliente y fecha me gustaría crear la variable secuencia de tal forma que me indique las visitas de un cliente. Así, el cliente 1 realiza 3 visitas. En la primera visita y en la segunda compra dos artículos y en la tercera compra tres artículos. La tabla está ordenada en función de Idcliente y por fecha. Me podéis ayudar?.
Yo hago lo siguiente pero no obtengo buenos resultados. Me gustaría añadir la función retain pero no sé como hacerlo. Si me pueden ayudar se lo agradecería
data datos;
set datos;
by idcliente fecha;
if first.fecha and first.idcliente then secuencia = 1;
else secuencia+1;
IdClient IdArtic Fecha Secuencia
1 23 01/01/2010 1
1 24 01/01/2010 1
1 45 05/01/2010 2
1 67 05/01/2010 2
1 56 20/01/2010 3
1 89 20/01/2010 3
1 90 20/01/2010 3
2 67 01/01/2010 1
2 6 01/01/2010 1
2 7 08/01/2010 2
2 45 08/01/2010 2
2 23 08/01/2010 2
Mira esto:
data datos (drop=secuencia);
input IdCliente IdArtic Fecha ddmmyy10. Secuencia;
format fecha ddmmyy10.;
datalines;
1 23 01/01/2010 1
1 24 01/01/2010 1
1 45 05/01/2010 2
1 67 05/01/2010 2
1 56 20/01/2010 3
1 89 20/01/2010 3
1 90 20/01/2010 3
2 67 01/01/2010 1
2 6 01/01/2010 1
2 7 08/01/2010 2
2 45 08/01/2010 2
2 23 08/01/2010 2
;
run;
data datos;
set datos;
retain secuencia;
by idcliente fecha;
if first.idcliente then secuencia=0;
if first.fecha then secuencia=secuencia+1;
run;
Utiliza variables auxiliares para entender mejor el funcionamiento.
Muchas Gracias!. La función retain es muy útil.
me salvaste la vida, una vez,
la principiante, Milagros..
una vez más, quise escribir…
Hola, tengo que rellenar las celdas vacías
1 2372 1
2 2356
3 2345
4 2334 2
5 2367
6 2398
las que estan debajo del 1 se bene llenar con 1´s y las que están debajo del 2 con 2´s, como podria hacerle con retain?
Gracias!
Hola,
Una forma de hacerlo con una variable auxiliar:
data datos;
input id1 id2 num;
datalines;
1 2372 1
2 2356 .
3 2345 .
4 2334 2
5 2367 .
6 2398 .
;run;
data datos2;
set datos;
retain num_aux 0;
if num= . then num_aux=max(num_aux,0);
else num_aux=num;
run;
Espero que te sirva. Saludos.
Hola tengo una base de datos muy grande, la estructura de la base de datos es: identificación del individuo(id), identificación del padre(idpad), identiticación de la madre (idmad) y sexo(sex). Quiero buscar en toda la columna de padres y madres si se encuentran como individuos. Ejemplo:
id idpad idmad sex
1 2 3 F
2 4 5 M
En éste caso el padre del individuo 1 se encuentra como individuo y quiero eliminar cualquiera de los dos renglones. Como le puedo hacer? Gracias
si en mi caso necesito llenar los missing, con la información encontrada en la celda (fila o registro) de la anterior y que no es missing, para el caso de una variable texto es decir:
Id Nombre Turno
1 Mario Mañana
2 Carlos
3 Lucia
4 Maria
5 Rafael
6 Luis Tarde
7 Ana
8 Erika
9 Adriana
10 Angelica Noche
11 Anny
12 Diana
13 Xavi
14 Tomas
15 Efrain
Y se espera llenar así:
Id Nombre Turno
1 Mario Mañana
2 Carlos Mañana
3 Lucia Mañana
4 Maria Mañana
5 Rafael Mañana
6 Luis Tarde
7 Ana Tarde
8 Erika Tarde
9 Adriana Tarde
10 Angelica Noche
11 Anny Noche
12 Diana Noche
13 Xavi Noche
14 Tomas Noche
15 Efrain Noche
Tengo una tabla en la cual la información que se muestra allí es las conexiones que realizan unos asesores al computador especifico, como hago para crear un código que me resuman por gestor los días y la hora en la que se conecta y como genero una frecuencia de la misma información ??
Gracias !!
Raul,
Muy bueno y muy útil para los princiìantes, me has abierto la luz con el if first. (…)
Saludos,
Pingback: Mínimo de una matriz de datos en SAS » Análisis y decisión
Tengo un fichero de datos donde una de las variables es la fecha de la operación «aaaammdd». Necesito identificar las operaciones por semana, es decir, agrupar los días en semanas reales y llamar a cada semana con un nombre para identificarlas.
Está claro que la forma más fácil es:
IF (FECHA >= ‘20150420’ AND FECHA =’20150427′ AND FECHA<='20150503')
THEN SEMANA = "20150427"; ……
…………..
Pero es un tanto rudimentario hacerlo así con toda las semanas del año, ¿se os ocurre alguna manera de hacerlo más mecánico?
Gracias.
Un saludo.
Raul te ha contestado con esta solución posible:
https://analisisydecision.es/truco-sas-identificar-el-lunes-de-cada-semana-para-clasificar-por-semanas/
Otra solución que te propongo es utilizar la opción ‘week.2’ dentro de la función intnx que hace incrementar las semanas partiendo del día lunes de cada semana en vez de domingo, y finalmente para simplificar la agrupación podrías crear una variable, por ejemplo semana_dentro_año, que contenga el número de semaña del año (aunque tendrás que corregirlo si tienes datos de diferentes años).
Data ejemplo;
format fecha lunes DDMMYY10.;
format lunes_formato_textolargo eurdfwkx30.;
fecha = ’01sep2015’d;
do i=1 to 100;
lunes=intnx(‘week.2′, fecha, i);
lunes_formato_textolargo=lunes;
semana_dentro_año=week(lunes,’w’);
output;
end;
drop fecha i;
Run;
Pingback: Truco SAS. Identificar el lunes de cada semana para clasificar por semanas | Análisis y Decisión
Hola!
Este es mi primer mensaje y estoy flipando con este blog, me lo estoy empoyando entero, muchas gracias.
Quiero hacer que en una variable llamada ‘como sea’, me haga la resta de la fila n+1 y la fila n
Ejemplo;
1 25 10 es decir: (35-25)
2 35 5 es decir: (40-35)
3 40 60 es decir: (100-40)
4 100
y así hasta el infinito. He probado con el first pero no me sale.
Gracias a todos por adelantado!
Me contesto a mi mismo. Lo he hecho con la función DIF que no sabía que existía. Previamente he ordenado el DS Ejemplo.
Data ejemplo;
set ejemplo;
by DN;
firstDN = first.DN;
IF first.DN THEN Resta=.;
ELSE Resta=dif(FR);
IF Resta =. THEN delete;
RUN;
Lo que hago es agruparlo por la variable DN, después creo la variable firstDN para ver en qué momentos cambia (aunque no es necesario). Cuando cambia el grupo hago que la variable «Resta» sea 0 ya que no me interesan las diferencias de valores de FR entre distintos grupos de DN, y si estamos dentro de un mismo grupo que me haga la resta entre la fila siguiente y la anterior (con Dif). Luego limpio las filas que me dan de resta 0 ya que no me valen para el estudio y listo.
Espero que le sirva a alguien.
Saludos a todos!
Hola!
Me pueden ayudar necesito desacumular los días que hay de un renglón a otro por cada cliente es decir obtener la columna dias2 del siguiente ejemplo:
Cliente dias dias2
S1 30 30
S1 61 31 es decir 61 – 30
S1 91 30 es decir 91 – 61
S1 121 30 es decir 121 – 91
S1 142 21 es decir 142 – 121
S2 30 30
S2 61 31 es decir 61 – 30
S2 92 31 es decir 92 – 61
Gracias!
Prueba a hacer:
data uno;
set datos;
keep cliente dias;
data dos;
set datos;
keep cliente dias;
dias = dias2;
data tres;
set uno dos;
proc sort ; by cliente;quit;
buenas!!
Soy totalmente nueva en SAS y tu blog me salva la vida en el trabajo
Tengo una base de datos por trimestres desde el 95 al 2017, a cada trimestre (son cuatro) se le asocia un dato. Tengo que sumar los cuatro trimestres del mismo año para crear una variable nueva pero no se como hacerlo…
Muchas gracias
hola tengo en una tabla SAS, registros que estan emparejados es decir con el mismo Id y mismo anno en el primero tengo fecha desde yvacia fecha hasta y en el segundo registro tengo vacia fecha desde y rellena fecha hasta y quiero dejarlo en un solo registro que tenga rellena la fecha desde y la fecha hasta, es posible?, como?
Gracias