lunes, 28 de abril de 2014

Calidad de datos: Detectar y eliminar duplicados en tablas SAS

En el siguiente post mostramos diferentes formas de detectar y eliminar duplicados en SAS. Es un problema que nos encontramos con frecuencia en el tratamiento de datos y que debe estar bien controlado para asegurar la calidad de nuestra información.



En primer lugar mostramos diferentes técnicas para detectar duplicados:

/* Creamos tabla de ejemplo */

data ventas(drop = i j);
length oficina $100.;
oficina = 'Madrid';
do j = 1 to 20;
producto = compress('P'||j);
unidades = round(ranuni(1)*20);
fecha = 20140401;
output;
if unidades > 15 then do;
       fecha = 20140402;
       output;
end;
end;
oficina = 'Barcelona';
do j = 1 to 20;
producto = compress('P'||j);
unidades = round(ranuni(1)*20);
fecha = 20140401;
output;
if unidades > 15 then do;
       fecha = 20140402;
       output;
end;
end;
oficina = 'Valencia';
do j = 1 to 20;
producto = compress('P'||j);
unidades = round(ranuni(1)*20);
fecha = 20140401;
output;
if unidades > 15 then do;
       fecha = 20140402;
       output;
end;
end;
oficina = 'Lisboa';
do j = 1 to 20;
producto = compress('P'||j);
unidades = round(ranuni(1)*20);
fecha = 20140401;
output;
if unidades > 15 then do;
       fecha = 20140402;
       output;
end;
end;
run;

/* 1. Detección duplicados vía proc sort:
Ordenamos por los campos en base a los que queremos detectar duplicados
con la clausula nodupkeys indicamos que elimine duplicados en la salida
en la clausula dupout indicamos dónde debe dejar los duplicados */

proc sort data=ventas out=ventas1 nodupkeys dupout=duplicados;
by oficina producto;
run;

/* 2. Detección duplicados vía proc sql:
Realizamos una agregado por los campos en base a los que queremos detectar duplicados
con la condición having nos quedamos con los que aparezcan más de 1 vez.
 */

proc sql;
create table duplicados as
(select oficina, producto, count(*)
from ventas
group by oficina, producto
having count(*) > 1);
quit;



/* 3. Combinar proc sort con sentencias fisrt y last. Detectamos los duplicados ordenando por la clave y buscando aquellos cuyo primer registro de una clave es diferente al último registro de esa clave. */

data ventas1;
set ventas;
clave = compress(oficina||producto);
run;

proc sort data=ventas1;
by clave;
run;

data duplicados;
set ventas1;
by clave;
if first.clave and not last.clave; /* Si no está duplicado el registro único debe ser first y last */
run;

/* 4. Empleando el procedimiento proc summary y quedandonos con los que tengan frecuencia mayor a 1 para la clave fijada */

proc summary data=ventas nway;
class oficina producto;
output out=duplicados(where=(_FREQ_>=2));
run;


El siguiente paso se trata de eliminar estos duplicados, según el criterio que establezcamos:


/* Eliminar */

/* Nos quedamos sólo con uno de los registros duplicados. Realizamos la eliminación
en base a diferentes criterios */

/* 1. Nos quedamos con el que tenga fecha más reciente */

proc sort data=ventas;
by oficina producto descending fecha; /* ordenamos por la fecha de forma descendente */
run;

proc sort data=ventas out=ventas1 nodupkeys;
by oficina producto;
run;


/* 2. Nos quedamos con el que cumpla un criterio fijado */

proc sort data=ventas;
by oficina producto;
run;


data ventas1;
retain oficina_ant producto_ant;
set ventas;
if (oficina_ant = oficina) and (producto_ant = producto) then do;
       if fecha <= 20140402 then delete; /* Borramos los registros duplicados que cumplan determinada condición */
end;
oficina_ant = oficina;
producto_ant = producto;
run;




1 comentario:

  1. Muy útil. Estaría bien disponer de una macro o similar para detectarlos de forma automática, en base a los campos que se le indique.

    ResponderEliminar