2011-10-11 10 views
5

Una duda sobre SAS:si _N_ = 1 condición devuelve cierto incluso si el conjunto de datos conjunto está vacío (cero observaciones) en SAS

data new; 
     set _NULL_; 
    run; 

    data _NULL_; 
     set new; 
     if _N_ = 0 then call execute ("%put empty dataset;"); 
     if _N_ = 1 then call execute ("%put non-empty dataset;"); 
    run; 

El bit de código anterior en mi entendimiento sólo debe imprimir el primer comentario, es decir, conjunto de datos vacío. Por alguna razón, está devolviendo también un verdadero para la segunda condición if e imprimiendo también un conjunto de datos no vacío.

Hágame saber ¿a dónde me está yendo mal con esto?

Respuesta

10

Bien, esto es lo que creo que está pasando. El primer problema es que las invocaciones de macro están entre comillas dobles y, por lo tanto, procesadas por el preprocesador antes de que SAS incluso haya comenzado a procesar el paso de datos (ejecutándose independientemente de si la condición if es verdadera o no). Debe poner el argumento a ejecutar en comillas simples en lugar de comillas dobles para evitar que el macropreprocesador lo ejecute prematuramente.

Este código aún no funcionará en un conjunto de datos vacío, sin embargo, como si el conjunto de datos suministrado en la línea configurada estuviera vacío, entonces todo el paso de datos finaliza antes de que se ejecute cualquier otro código.

En tercer lugar, _N_ se inicializa en 1, no en 0, y se incrementa desde allí en el límite del paso de datos, por lo que la condición _N_ = 0 siempre será falsa.

Una forma alternativa de ir sobre esto sería el uso de la nobs = opción para establecer como sigue:

data _NULL_; 
    if 0 then set new nobs=num_obs; 
    if num_obs = 0 then call execute ('%put empty dataset;'); 
    if num_obs > 0 then call execute ('%put non-empty dataset;'); 
stop; 
run; 

El if 0 then es una condición maniquí usado para forzar la ejecución del código de paso de datos; si se utilizara una declaración de conjunto desnudo, la ejecución no continuaría más allá de la línea establecida si el conjunto de datos "nuevo" estuviera vacío.

Una mejor opción podría ser usar macros para abrir el conjunto de datos y leer el cualquier atributo:

%let dsid = %sysfunc (open(dataset_name)); 
%let anyobs = %sysfunc (attrn(&dsid,ANY)); 
%let dsid = %sysfunc (close(&dsid)); 

La variable macro &anyobs habrá 1 si dataset_name contiene al menos una observación (fila) y al menos una variable (columna), 0 si no contiene observaciones, pero al menos una variable, y -1 si no contiene observaciones ni variables.

+0

Gracias Gary! Tu respuesta es realmente útil. –

+0

Buena respuesta integral –

Cuestiones relacionadas