/head>

Una macro muy sencilla que ha aparecido en un programa de funcionalidades y que busca registros duplicados en tablas SAS. Es muy sencilla y a alguien puede serle útil y para eso estamos, para compartir conocimientos aunque sean sencillos. Pocos somos los que compartimos nuestro conocimiento y encima poniendo nuestro dinero, en fin, que me distraigo del tema.

%macro busca_duplicados ( dataset, campo);
proc sql;
create table duplicados (where=(frec>1)) as select
&campo.,
count(*) as frec
from &dataset.
group by 1;
quit;
%mend;

No pongo ni ejemplo de uso, muy fácil. Pero ya verás como alguien le saca partido. Y todo esto de forma altruista, insisto, que si no me valoro yo no me valora nadie. Saludos.

18 pensiamientos en “Macros (fáciles) de SAS. Busca duplicados

  • Mireya

    Fantastico, muchas gracias por ahorrarnos trabajo.

    Salu2

    Responder
  • rvaquerizo

    Creo que pueden tener mucho éxito los trucos fáciles y de estos tengo miles.

    Responder
  • rvaquerizo

    Creo que pueden tener mucho éxito los trucos fáciles y de estos tengo miles.

    Responder
  • Alex

    Muchas gracias

    Responder
  • rvaquerizo

    De nada. Busca las dudas en el blog primero, al final siempre son las mismas.

    Responder
  • Julian

    Que tal.

    Aprovechando que se anima ha enseñar cosas faciles…. nos podria decir paso a paso como funciona una macro y posteriormente como la envocamos.

    Gracias

    Responder
  • rvaquerizo

    Sobre el mismo programa.

    *MACRO CON 2 PARAMETROS UN CONJUNTO DE DATOS Y UN CAMPO
    QUE PUEDE CONTENER DUPLICADOS;
    %macro busca_duplicados ( dataset, campo);
    proc sql;
    /*CREAMOS LA TABLA DUPLICADOS PERO CUANDO LA ESCRIBIMOS
    EL CAMPO FREC HA DE SER MAYOR QUE 1, ES UNA OPCION DE
    ESCRITURA*/
    create table duplicados (where=(frec>1)) as select
    /*REALIZAMOS LA CONSULTA, SOLO EL CAMPO CON POSIBLES DUPLICADOS
    Y UN CONTEO DEL NUMERO DE VECES QUE APARECE. EVIDENTEMENTE AGRUPAMOS
    POR EL CAMPO.*/
    &campo.,
    count(*) as frec
    from &dataset.
    group by 1;
    quit;
    %mend;

    Es una tabla de frecuencias con SQL, pero en el momento de la escritura nos quedamos con aquellos registros que tienen una frecuencia superior a 1.

    Responder
  • Salva

    Para invocar la macro tan solo habría que poner debajo de la misma:

    %busca_duplicados(librería.dataset, campo);

    El primer parámetro de la macro es la tabla en la que se quiere buscar los duplicados y el segundo el campo de la tabla en el que se quieren buscar los duplicados.

    Saludos

    Responder
  • Dani Fernández.

    El título del post ya lo dice todo: “Macros (fáciles) de SAS”, que a efectos didácticos (y poniendo de su bolsillo) hemos de agradecer a Raúl. Ya hubiera querido yo en mis inicios de SAS tener donde poder consultar mis dudas en español e incluso mejor aún hacerme una idea de como se trabaja el data mining en el mundo profesional.
    Así que aprovecho para añadir mis sugerencias (hacía tiempo que no participaba en tu web, eh Raul!):
    Lo más normal es que uno vaya al grano y directamente te quedes con un dataset sin duplicados. Tomando como referencia el dataset ‘class’ que todo SAS Base lleva incorporado entre otros podemos hacerlo de diferentes maneras:

    proc sql;
    create table NO_duplicados as
    select distinct age
    from sashelp.class;
    quit;
    Sencillamente te quedas con todos los valores (de edades en nuestro ejemplo) que son distintos, es decir, sin repeticiones o duplicados.

    Tambien podemos hacerlo mediante el Proc Sort, este “procedure” nos dice (en el LOG) el número de duplicados que ha encontrado y borrado para dejarnos la tabla solo con valores distintos:
    proc sort data=sashelp.class
    out=edades (keep= age) NODUPKEY;
    by age ; run;

    Tambien podríamos hacerlo mediante Proc Freq (no olvidemos añadir la opción “noprint” si no queremos que nos imprima el listado) que se asemeja mucho al ejemplo de la macro de Raul al usar tambien la clausula “where” pero siendo en este caso la variable “count” fija por defecto de este procedure (mientras que Raul la creó podiendola nombrar de otra manera al realizar el count(*), es decir, la variable “frec” de su código es similar a la variable count que trae el proc freq por defecto:

    proc freq data=sashelp.class noprint;
    tables age /out=duplicados (where=(count>1) keep=age count);
    run;

    No obstante, a efectos de limpieza de datos (data cleansing) a mí me gusta usar un código como el siguiente que me reporta no solo un dataset con valores distintos sino tambien un segundo dataset con aquellos valores duplicados. Este código requiere que el dataset ya venga ordenado previamente, sino debemos ordenar primero:

    proc sort data=sashelp.class out=edades (keep= age) ; by age ; run;

    A continuación:

    data
    duplicados
    NO_duplicados;
    set edades;
    by age;
    if first.age
    then output no_duplicados;
    if first.age and not last.age
    then output duplicados;
    run;

    Por cierto, para llamar a una macro NO es necesario escribir el “;” final. El lenguaje macro SAS es diferente del lenguaje SAS Base.
    Tambien dejar claro a Julian que el orden de los parámetros de la macro no importa, esta la podríamos invocar:
    %busca_duplicados(campo,librería.dataset)

    un saludo,
    Dani Fernández.

    Responder
  • Dani Fernández.

    Cuando dije:
    “El lenguaje macro SAS es diferente del lenguaje SAS Base.” me refiero a que existen sus diferencias, aunque aparentemente son tan similares que al que se inicia en macros SAS le asaltan dudas confusas cuando ve que un codigo SAS Base lo implanta en macro y entonces deja de funcionarle o funciona de otra manera.

    Dani Fernandez.

    Responder
  • rvaquerizo

    Joder Dani, cuanto tiempo. El nodupkey requiere una entrada por si sólo. Yo recomiendo el uso de datos agrupados con BY como el último ejemplo de Dani.

    Responder
  • carme deulofeu

    Dani, usando tu programa donde el 2o dataset te guarda los duplicados, tal como lo tienes te guarda las mismas entradas que mantiene en el primer dataset. Yo lo he corregido (ya que tengo información diferente que necesito guardar) haciendo el siguiente cambio:

    data
    duplicados
    NO_duplicados;
    set edades;
    by age;
    if first.age
    then output no_duplicados;
    if last.age and not first.age
    then output duplicados;
    run;

    de esta manera te guarda toda la información.

    No se que pasará cuando tenga 3 entradas del mismo individuo pero te lo digo cuando pase.

    Carme.

    Responder
  • carme deulofeu

    Por cierto gracias, me han sido muy útiles.

    Carme.

    Responder
  • Alberto

    Hola, tengo una lista de números ej:

    10
    10
    10
    5
    5

    Y por cada registro repetido le tengo que añadir un número de la serie 1,2,3… quedando

    101
    102
    103
    51
    52

    ¿Cómo se podría hacer?

    Responder
  • rvaquerizo

    data uno;
    input xx;
    datalines ;
    10
    10
    10
    5
    5
    ;run;

    proc sort data=uno; by xx; run;

    data uno;
    set uno;
    retain pos;
    by xx;
    if first.xx then pos=1;
    else pos=pos+1;
    run;

    Ya concatenas las variables. Saludos.

    Responder
  • Alberto

    Muchas gracias. Me ha ayudado mucho. Decirte que miro mucho tu web para temas de consulta y sin esta página me resultaría muy complicado avanzar profesionalmente. Te lo agradezco infinitamente. Ayudas a mucha gente, te lo aseguro.

    Ánimo.

    Responder
  • Natalia

    Necesito quitar duplicados en una tabla de SAS, y quedarme con el que tenga la ultima fecha de modificación o que tengan estado COMPLETADO O CANCELADO.
    Campos: nro de orden.(que es lo que se repite en mi archivo ya que se registran todos los estados que ha pasado). Podrías ayudarme please?, gracias!!!!

    Responder
  • rvaquerizo

    Mírate esta entrada. http://analisisydecision.es/monografico-datos-agrupados-en-sas/

    Se trata de ordenar por el campo que quieres y con by en un paso data te quedas con el último o con el primer registro. Saludos.

    Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *