2011-04-14 19 views

Respuesta

17

Es fácil con PROC SQL. Haz un conteo y pon los resultados en una variable macro.

proc sql noprint; 
select count(*) into :observations from library.dataset; 
quit; 
+0

Gracias a Laurent por la respuesta rápida. Parece que ** seleccionar en ** es muy útil. – mj023119

+5

Hola Laurent: Esto está bien para conjuntos de datos pequeños, pero para grandes conjuntos de datos puede llevar mucho tiempo ejecutarlos, ya que tiene que leer cada observación en lugar de solo mirar los metadatos de la tabla. Vea algunas de las otras respuestas a continuación para un enfoque más eficiente. –

+1

'count (var_name)' lee cada observación, pero 'count (*)' no. – Ryan

13

Hay un montón de diferentes maneras, que tienden a utilizar una función macro con open() y attrn(). A continuación se muestra un ejemplo simple que funciona bien la mayor parte del tiempo. Si va a tratar con vistas de datos o situaciones más complejas como tener un conjunto de datos con registros marcados para eliminación o cláusulas where activas, entonces es posible que necesite una lógica más sólida.

%macro nobs(ds); 
    %let DSID=%sysfunc(OPEN(&ds.,IN)); 
    %let NOBS=%sysfunc(ATTRN(&DSID,NOBS)); 
    %let RC=%sysfunc(CLOSE(&DSID)); 
    &NOBS 
%mend; 

/* Here is an example */ 
%put %nobs(sashelp.class); 
+0

Gracias de todos modos, Johns. Lo intentaré más tarde. – mj023119

+0

Esto no funciona para una 'VISTA' en SAS 9.3 – JustinJDavies

+0

No es estrictamente relevante. Pero a veces pienso que es una forma muy complicada. En R, el comando relevante es nrow (data.frame1) – xiaodai

8

Este es el ejemplo más completo del que hablaba @cmjohns. Devolverá 0 si está vacío, -1 si falta y tiene opciones para manejar las observaciones eliminadas y las cláusulas where (tenga en cuenta que el uso de una cláusula where puede hacer que la macro tome mucho tiempo en conjuntos de datos muy grandes).

Notas

de uso:

Esta macro devolverá el número de observaciones en un conjunto de datos. Si el conjunto de datos no existe, se devolverá -1. No recomendaría esto para su uso con nombres de libras ODBC, úsela solo en tablas SAS.

Parámetros:

  • IDS - El libname.dataset que desea comprobar.
  • iWhereClause (Opcional) - una cláusula WHERE de aplicar
  • iNobsType (Opcional) - O NOBS O NLOBSF. Ver SASV9 documentation para descripciones.

definición de macro:

%macro nobs(iDs=, iWhereClause=1, iNobsType=nlobsf, iVerbose=1); 
    %local dsid nObs rc; 

    %if "&iWhereClause" eq "1" %then %do; 
    %let dsID = %sysfunc(open(&iDs)); 
    %end; 
    %else %do; 
    %let dsID = %sysfunc(open(&iDs(where=(&iWhereClause)))); 
    %end; 

    %if &dsID %then %do; 
    %let nObs = %sysfunc(attrn(&dsID,nlobsf)); 
    %let rc = %sysfunc(close(&dsID)); 
    %end; 
    %else %do; 
    %if &iVerbose %then %do; 
     %put WARNING: MACRO.NOBS.SAS: %sysfunc(sysmsg());  
    %end; 
    %let nObs = -1; 
    %end; 
    &nObs 
%mend; 

Ejemplo de Uso:

%put %nobs(iDs=sashelp.class); 
%put %nobs(iDs=sashelp.class, iWhereClause=height gt 60); 
%put %nobs(iDs=this_dataset_doesnt_exist); 

Resultados

19 
12 
-1 

instalación

recomiendo la creación de un SAS autocall library y la colocación de esta macro en su ubicación autocall.

+0

Hola Rob, supongo que también eres un usuario avanzado de SAS. Voy a probar cuando entiendo el código. Gracias de todos modos, de todos modos. – mj023119

+0

Robert, ¿sabría cómo modificar para determinar también si no hay ni obs ni vars? Devuelve 1 en esa situación. Intenté jugar con varias opciones de attrn pero no puedo encontrar el camino. – milcak

+1

@milcak Claro, el código que necesita para probar el número de variables es '% let nVars =% sysfunc (attrn (& dsID, nvars));'. Esta línea de código debería ejecutarse donde se está ejecutando la instrucción '% let nobs'. Dejaré el resto de la lógica para que averigües qué valor quieres devolver. –

3

Proc sql no es eficiente cuando tenemos un gran conjunto de datos.Aunque el uso de ATTRN es buen método, pero esto se puede lograr dentro de SAS base, aquí está la solución eficiente que puede dar el número de obs de incluso miles de filas con sólo leer una fila:

data DS1; 
set DS nobs=i; 
if _N_ =2 then stop; 
No_of_obs=i; 
run; 
+2

+1 para una solución que no usa esos temidos signos '%', solo tenga en cuenta que hay casos en que 'nobs' no funcionará. http://www2.sas.com/proceedings/sugi26/p095-26.pdf –

1

El truco está produciendo una salida incluso cuando el conjunto de datos está vacío.

data CountObs; 

    i=1; 
    set Dataset_to_Evaluate point=i nobs=j; * 'point' avoids review of full dataset*; 
    No_of_obs=j; 
    output; * Produces a value before "stop" interrupts processing *; 
    stop; * Needed whenever 'point' is used *; 
    keep No_of_obs; 
run; 

proc print data=CountObs; 
run; 

El código anterior es la forma más sencilla que he encontrado para producir el número de observaciones, incluso cuando el conjunto de datos está vacía. He oído que NOBS puede ser complicado, pero lo anterior puede funcionar para aplicaciones simples.

+0

Debe mover la declaración de salida ANTES de la instrucción set para permitirle manejar datos de entrada con cero observaciones. – Tom

1

Un enfoque ligeramente diferente:

proc contents data=library.dataset out=nobs; 
run; 

proc summary data=nobs nway; 
class nobs; 
var delobs; 
output out=nobs_summ sum=; 
run; 

Esto le dará un conjunto de datos con una observación; la variable nobs tiene el valor de número de observaciones en el conjunto de datos, incluso si es 0.

1

Creo que estoy tratando de reinventar la rueda aquí con tantas respuestas ya. Pero sí veo algunos otros métodos que intentan contar desde el conjunto de datos real; esto podría llevar mucho tiempo para grandes conjuntos de datos. Aquí hay un método más eficiente:

proc sql; 
select nlobs from sashelp.vtable where libname = "library" and memname="dataset"; 
quit; 
+1

Realmente necesita usar NLOBS en lugar de NOBS. Esa variable tiene en cuenta el número de observaciones eliminadas (DELOBS). – Tom

+0

Gracias Tom! Edité mi consulta. – enautic

+0

Buena adición. También hay 'dictionary.tables' si no quieres usar' sashelp.vtable' también. No recuerdo la circunstancia exacta, pero alguna vez tuve una situación en la que uno de ellos tardó casi 30 segundos en correr, mientras que el otro fue instantáneo. P.ej. 'proc sql noprint; seleccione nlobs de dictionary.tables donde libname = 'SASHELP' y memname = 'CLASS'; salir; ' –

Cuestiones relacionadas