Truco SAS. Transponer tablas con PROC TRANSPOSE, DATA o PROC SQL
Agosto 27th, 2009 | por rvaquerizo |Para transponer datasets disponemos en SAS del PROC TRANSPOSE. El ahora escribiente no es muy partidario de emplearlo. Prefiero otras metodologías para transponer conjuntos de datos SAS. Voy a trabajar con un ejemplo que os servirá para aproximaros al TRANSPOSE y para entender mejor las opciones de lectura de un PASO DATA y el funcionamiento del PROC SQL. La idea es, partiendo de una tabla de hechos por meses, transponer un campo importe. Vamos a simular una tabla con esa estructura:
data hc_mes_importe;
do idcliente=1 to 1000000;
do mes=200901 to 200903;
importe=rand("uniform")*ranpoi(3,10000);
output;
end;end;
run;
Tenemos 3 registros por cada idcliente correspondientes a los meses de 200901 a 200903. La idea es transponer la tabla de forma que el importe que ahora está en filas pase a ser columnas y tengamos un solo registro para cada idcliente. El primer método que tenemos es el uso del TRANSPOSE:
proc transpose data=hc_mes_importe prefix=imp
out=t_mes_importe (drop=_name_);
id mes;
by idcliente;
quit;
Esta es la estructura más simple del TRANSPOSE. En prefix indicamos el prefijo que deseamos para la nueva variable. En el dataset de salida eliminamos la variable nombre que genera SAS por defecto. Evidentemente transponemos por idcliente y en la instrucción ID ponemos el campo que identifica las columnas. Esta es la sintaxis más habitual del TRANSPOSE, a continuación os planteo como transponer mediante un paso DATA:
data t_mes_importe;
merge hc_mes_importe (rename=importe=imp200901 where=(mes=200901))
hc_mes_importe (rename=importe=imp200902 where=(mes=200902))
hc_mes_importe (rename=importe=imp200903 where=(mes=200903));
by idcliente;
run;
Esta forma de transponer es la unión horizontal de una tabla consigo misma tantas veces como meses disponemos por idcliente. Necesitamos renombrar la variable para no quedarnos con sólo una columna. Otro modo de transponer tablas y que a mi me gusta particularmente es el uso del PROC SQL:
proc sql;
create table t_mes_importe as select
idcliente,
sum(importe*(mes=200901)) as imp200901,
sum(importe*(mes=200902)) as imp200902,
sum(importe*(mes=200903)) as imp200903
from hc_mes_importe
group by 1;
quit;
Lo que hacemos es sumarizar por el campo del que deseamos un registro único y operamos con los campos que vamos a transponer. Esta operación es el importe multiplicado por una condición.
Si ejecutáis los códigos que os propongo encontraréis que el paso DATA es el más eficiente, el PROC SQL tarda un 75% más y el TRANSPOSE un 250% más. Por otro lado el TRANSPOSE podría ser mejor en códigos automáticos ya que no necesitamos parámetros, pero si trabajamos con macros al final el paso DATA es más efectivo. A futuro empezaremos a parametrizar este tipo de sentencias SAS.
Por supuesto si tenéis cualquier duda o sugerencia… rvaquerizo@analisisydecision.es

12 Respuestas en “Truco SAS. Transponer tablas con PROC TRANSPOSE, DATA o PROC SQL”
Por ELIZABETH FLOREZ, Oct 26, 2009 | Responder
HOLA! FELICITÁNDOLES DE ANTEMANO POR SU VIRTUOSA AYUDA!…
QUISIERA PREGUNTAR CÓMO PUEDO IR ELIMINANDO TABLAS DESDE UN PROGRAMA SAS, YA QUE A VECES SOLO QEREMOS QUEDARNOS CON UNA SOLA AL FINAL Y CON ANTELACIÓN LA EJECUCIÓN NOS HA DEJADO UN MONTÓN QUE PUEDE DIFICULTARNOS IDENTIFICAR AQUELLA QUE NOS INTERESA, SALUDOS…
Por rvaquerizo, Oct 26, 2009 | Responder
emplea el proc delete data=… ; run; así eliminas tablas sas.
Por Fran Gonzalez, Ene 28, 2010 | Responder
Hola, cómo puedo borrar una fila de una archivo?
Gracias!
Por rvaquerizo, Ene 28, 2010 | Responder
Hola. Si te sabes la fila a borrar puedes hacer:
data tabla;
set tabla;
if _n_=fila then delete;
run;
Saludos.
Por Miguel, Oct 5, 2010 | Responder
Hola.
En el caso de que disponga de la siguiente tabla:
IDCLIENTE MES IMPORTE
1 1 100
1 1 100
2 1 200
2 2 200
3 1 400
3 2 400
3 3 400
Se supone que el cliente 1 se ha gastado 100, el 2 200 y el 3 400.(el importe esta repetido)
Con estos datos. Como indicarías el gasto mensual por cliente? y la media mensual?
Por rvaquerizo, Oct 5, 2010 | Responder
No entiendo, tienes un dato por mes. No tiene sentido un total o una media mensual.
Por Miguel, Oct 6, 2010 | Responder
Creo que me expresado mal. 1 se corresponde con enero.Así para el mes de enero el gasto sería de 800, para febrero de 400 y para marzo de 400.
Al final he aplicado un select UNIQUE y he conseguido que no se repitan las observaciones.
Muchas Gracias!
Por Alberto, Abr 27, 2011 | Responder
muchas gracias… fenomenal post.
Por rvaquerizo, Abr 27, 2011 | Responder
Gacias a ti. Casi nadie entiende esta entrada. Pero creo que eso es porque nadie ejecuta el código SAS. Fíjate si es fácil copiar y pegar.
Por Irene, Jul 15, 2011 | Responder
Muy Util esta entrada raul!!
Muchas gracias!!! :)
Por Sanweb, Sep 27, 2011 | Responder
¿Sabeis como deshacer el proc traspose?
Me explico: tengo varios ficheros del tipo,
Cliente 01/09/2011 02/09/2011 03/09/2011
Pablo 5 6 7
Genaro 8 9 3
Y me gustaría obtener:
Cliente Fecha Altas
Pablo 01/09/2011 5
Pablo 02/09/2011 6
Pablo 03/09/2011 7
Genaro 01/09/2011 8
Genaro 02/09/2011 9
Genaro 03/09/2011 3
MUCHAS GRACIAS!!!
Por rvaquerizo, Sep 27, 2011 | Responder
data uno;
input cli $ f1 f2 f3;
datalines;
pablo 5 6 7
genaro 8 9 3
;run;
proc sort data = uno; by cli; quit;
proc transpose data=uno
out=dos (rename =(_name_=f col1=altas));
by cli;
var f1 f2 f3;
quit;
Saludos.