Vamos a estudiar cómo funciona CASE en un PROC SQL. Son palabras que aparecen en las búsquedas de Google y también he observado que el número de visitas al blog ha descendido en los últimos días, y no sólo es debido a las vacaciones navideñas. El 60% de los clics a AyD vienen por temas de SAS y, en los últimos días, tengo muy olvidados los mensajes de esta categoría. Además, en el plazo de dos días voy a dejar de trabajar con esta herramienta, por lo que es posible que se reduzcan aún más. En fin, a lo que voy: CASE en el PROC SQL.
CASE nos permite crear campos condicionales dentro del bloque SELECT de una query de PROC SQL:
* DATASET ALEATORIO;
data aleatorio;
do i = 1 to 200;
grupo1 = 1;
if mod(i, 2) = 0 then grupo1 = 2;
if mod(i, 3) = 0 then grupo1 = 3;
grupo2 = rand("binomial", 0.05, 5);
normal = rand("normal");
uniforme = rand("uniform") * 1000;
if grupo1 = 1 then uniforme = .;
poisson = ranpoi(34, 25);
output;
end;
run;
Partimos de un dataset aleatorio de 200 observaciones con dos variables de grupo y tres variables aleatorias. Un ejemplo sencillo de uso en una consulta de selección:
proc sql;
title "Ejemplo de uso de CASE 1";
select grupo1,
case
when grupo2 <= 1 then "tipo 0-1"
else "tipo 2"
end as nuevo_grupo2,
sum(distinct poisson) as suma_distintas_poisson
from aleatorio
group by 1, 2;
quit;
La estructura es bien sencilla:
CASE
WHEN condición1 THEN valor1
...
WHEN condiciónN THEN valorN
ELSE valorN+1
END AS nombre
Las condiciones son excluyentes y necesitamos finalizar la sentencia con ELSE ... END AS. Es muy práctico para agrupar cualquier tipo de variable; las condiciones pueden incluir más variables, tanto numéricas como carácter o una mezcla de todas:
proc sql;
title "Ejemplo de uso de CASE 2";
select
/* CONDICIONALES NUMÉRICAS */
case
when normal < 0 then "NEGATIVA"
else "POSITIVA"
end as signo_normal,
/* MEZCLA DE CONDICIONALES */
case
when poisson > 30 then "TIPO x-30"
when grupo1 <= 2 then "TIPO 2-30"
else "TIPO 3-x"
end as nuevo_grupo,
min(poisson) as min_poisson,
max(poisson) as max_poisson,
sum(uniforme) as suma_uniforme
from aleatorio
group by calculated signo_normal, calculated nuevo_grupo;
quit;
No sólo pueden ser variables agrupadoras; también se pueden realizar sumarizaciones con CASE. Un ejemplo forzado (y absurdo):
proc sql;
title "Ejemplo de uso de CASE 3";
select grupo1,
sum(case
when grupo2 = 1 then poisson * 10
when grupo2 <= 3 then poisson * 5
else poisson * 2
end) as multiplica
from aleatorio
group by 1
order by 2;
quit;
Espero que sea útil este breve mensaje. Pero sobre todo espero que perdáis el miedo a esta función; no es de uso muy habitual entre los programadores de SAS. Saludos.