Mi è capitato talvolta di dover contare il numero di osservazioni di un dataset. Ad esempio, per verificare che il dataset non fosse vuoto, ossia senza osservazioni.
Se ti trovi anche tu in questa situazione, sappi che, come spesso succede, esistono diversi modi in SAS per risolvere questo “problema”. In questo post voglio illustrarti i 6 modi che mi è capitato di utilizzare in passato e per ciascuno di dirò quelli che, a mio parere, sono i pro e i contro.
Ah, ovviamente, sto parlando di un conteggio eseguito tramite script…insomma, fare right-click sul nome del dataset e controllare il numero di osservazioni tra le proprietà…non vale 😁
Cominciamo…
1° modo: PROC SQL
Il primo modo con il quale puoi contare il numero di osservazioni di un dataset consiste nell’utilizzare l’operatore COUNT(*) della PROC SQL. Ad esempio:
proc sql;
select count(*) as n
from sashelp.class;
quit;
Pro: è sicuramente un modo facile da ricordare e veloce da scrivere.
Contro: diventa estremamente inefficiente quando si ha a che fare con dataset di grandi dimensioni, in quanto SAS deve scorrere tutte le osservazioni dalla prima all’ultima per poterne contare il numero.
2° modo: PROC CONTENTS
Il secondo modo per contare il numero di osservazioni di un dataset consiste nel ricorrere alla PROC CONTENTS. Questa procedura ha un output molto ricco di informazioni, tra cui ovviamente, è riportato il numero di osservazioni del dataset. Vediamo un esempio:
proc contents data = sashelp.class noprint out = contents; run; data _null_; set contents (obs = 1); /* Leggo il numero di osservazioni del dataset SASHELP.CLASS, salvato nella variabile nobs, e "registro" l'informazione nella macro-variabile NUMREC */ call symputx("NumRec", nobs); run; /* Stampo l'info nel LOG */ %put "Il numero di record è: &numrec" ;
Questo codice stamperà nel LOG il numero di record “salvato” nella macro variabile &numrec.
Pro: è un modo veloce di ottenere l’informazione desiderata, in quanto non richiede la lettura completa delle osservazioni del dataset ma solo della parte “descrittiva” dello stesso.
Contro: richiede l’utilizzo di un PROC STEP e di un DATA STEP per ottenere una semplice informazione come il numero di record di una tabella (…a meno che non ci si “accontenti” della stampa a video dell’informazione). È un metodo forse un po’ troppo “verboso” per un compito così elementare, non trovi?
3° modo: SASHELP.VTABLE
Il terzo modo per contare il numero di osservazioni di un dataset consiste nel recuperare questa informazione dalla vista SASHELP.VTABLE. Questa vista è creata e aggiornata automaticamente da SAS e contiene diverse informazioni relative a tutte le tabelle “registrate” durante la sessione SAS corrente tra cui, ovviamente, il numero di osservazioni di ciascuna di esse. Vediamo un paio di esempi, su come recuperare il numero di osservazioni del dataset SASHELP.CLASS leggendo la vista SASHELP.VTABLE:
/* Modo 3.1 */
data _null_;
set sashelp.vtable;
/* Seleziono la riga corrispondente alla tabella
di cui mi interessa contare i record */
where libname = "SASHELP" and memname = "CLASS";
put 'Il numero di record è : ' nobs;
run;
/* Modo 3.2 */
data _null_;
set sashelp.vtable;
/* Seleziono la riga corrispondente alla tabella
di cui mi interessa contare i record */
where libname = "SASHELP" and memname = "CLASS";
call symputx ("Nrec",nobs);
run;
%put "il numero di record è: &NREC";
I due esempi, sono sostanzialmente identici: entrambi stampano l’informazione sul LOG. La differenza sta nel fatto che, nel secondo caso, il contenuto della variabile NOBS è registrata in una macro-variabile. Personalmente, è la soluzione che preferisco in quanto consente di utilizzare l’informazione anche al di fuori dell’ambito ristretto del passo di data nel quale viene creata, come invece avviene nel primo caso.
Pro: è un modo elegante per ottenere l’informazione desiderata, utilizzando poche righe di codice.
Contro: potrebbe divenire inefficiente nel momento in cui ci sono molte tabelle “registrate” nella sessione corrente con conseguente aumento delle “dimensioni” della vista SASHELP.VTABLE.
4° modo: END =
Il quarto modo che voglio illustrarti per contare il numero di osservazioni di un dataset consiste nell’utilizzare l’opzione END = e la variabile _N_ nell’ambito di un passo di data . Ecco un esempio:
data _null_;
set sashelp.class end = eof;
/* In corrispondenza dell'ultimo record del dataset,
la variabile temporanea eof = 1 e allora salvo il numero
del record corrispondente (_N_)
nella macro-variabile NumRec */
if eof then call symputx("NumRec", _N_) ;
run;
%PUT "Il numero di record è: &NumREC";
Anche in questo caso, il risultato è stampato nel LOG.
Pro: è un modo elegante per ottenere l’informazione desiderata, utilizzando poche righe di codice.
Contro: SAS legge tutte le osservazioni dalla prima all’ultima, quindi questa soluzione potrebbe divenire inefficiente se la tabella da leggere è molto grande. Inoltre, non funziona se il dataset è vuoto, ossia ha zero osservazioni.
5° modo: NOBS =
Il quinto modo è per certi versi simile al precedente e consiste nell’utilizzare l’opzione NOBS = nell’ambito di un passo di data. Ad esempio:
data _null_;
set sashelp.class nobs = n;
call symputx ("numerorec", n) ;
stop;
run;
%put "sahelp.class contiene &numerorec record!";
Pro: richiede poche righe di codice per essere implementato ed veloce nell’esecuzione, dato che non richiede la lettura dell’intero dataset.
Contro: non funziona se il dataset è vuoto, ossia ha zero osservazioni oppure se nello stesso sono presenti osservazioni marcate per la cancellazione. Come affrontare quest’ultima situazione…sarà oggetto di un prossimo post…😉
6° modo: ATTRN()
Il sesto modo e ultimo modo per contare il numero di osservazioni di un dataset che voglio illustrarti, consiste nell’utilizzare la funzione ATTRN(). Anche in questo caso, ti mostro due esempi, di fatto equivalenti.
Il primo ricorre alla funzione ATTRN() nell’ambito di un passo di data:
data _null_;
dsname = "sashelp.class";
dsid = OPEN(dsname);
nobs = ATTRN(dsid,"nobs");
put 'Il numero di osservazioni del dataset ' dsname 'è: ' nobs;
run;
Il secondo esempio utilizza la funzione ATTRN() con il linguaggio MACRO:
%let DS = sashelp.class;
%let DSID = %sysfunc(OPEN(&DS,IN));
%let NOBS = %sysfunc(ATTRN(&DSID,NOBS));
%let RC = %sysfunc(CLOSE(&DSID));
%put "Numero di osservazioni del dataset &DS : &NOBS";
Pro: è un modo elegante per ottenere l’informazione desiderata, utilizzando poche righe di codice. Inoltre funziona bene anche se il dataset è vuoto, ossia ha zero osservazioni.
Contro: potrebbe sembrare ostico “a prima vista” e difficile da ricordare.
Eccoci in fondo! Questi sono i metodi che conosco per contare il numero di osservazioni in un dataset. Come hai visto ce n’è per tutti i gusti e per diverse situazioni.
Spero allora che questo articolo ti possa essere utile.
Ciao, alla prossima!
SAS e tutti gli altri nomi di prodotti e servizi di SAS Institute Inc. sono marchi registrati di SAS Institute Inc. negli USA e in altri paesi. ® indica la registrazione negli USA.
ma se invece delle osservazioni io volessi contare le variabili? ovvero mi serve sapere il numero di colonne?
"Mi piace""Mi piace"
Ciao Mimmo, domanda interessante.
Il primo modo che mi viene in mente è quello di sfruttare gli ARRAY SAS. Ad esempio così:
data _null_;
set sashelp.class;
array n _numeric_; /* Definisco un array costituito da tutte le variabili numeriche del dataset */
array c _character_; /* Definisco un array costituito da tutte le variabili alfanumeriche del dataset */
nvar = dim(n) + dim(c); /* Calcolo qui il numero di variabili del dataset */
put “Il numero di variabili del dataset è: ” nvar; /* Stampo il risultato nel LOG */
stop; /* Mi fermo alla prima osservazione */
run;
Oppure, volendo sfruttare il linguaggio MACRO:
data _null_;
set sashelp.class;
array n _numeric_; /* Definisco un array costituito da tutte le variabili numeriche del dataset */
array c _character_; /* Definisco un array costituito da tutte le variabili alfanumeriche del dataset */
call symput (“nvar”, sum(dim(n),dim(c))); /* Calcolo qui il numero di variabili del dataset e lo salvo nella MACRO &NAVR */
stop; /* Mi fermo alla prima osservazione */
run;
%let nvar = &nvar; /* questo solo per rimuovere gli spazi iniziali dalla macro variabile */
%put Il numero di variabili del DS è: &nvar; /* Stampo il risultato nel LOG */
Tuttavia, il modo più classico di contare il numero di variabili di un dataset, consiste forse nel ricorrere alla PROC CONTENTS:
proc contents data = sashelp.class noprint out = class_cont;
run;
Il dataset temporaneo class_cont contiene tutte le informazioni relative alle variabili del dataset sashelp.class.
Il dataset out = è costituito da tante righe quante sono le variabili del dataset in lettura. In questo caso 5, appunto.
Ora ti trovi nel caso in cui devi contare il numero di righe di un dataset e puoi utilizzare uno dei metodi che ho provato ad illustrare nel post. Ad esempio:
proc sql noprint;
select count(*) into: nvarsql
from class_cont;
quit;
%let nvarsql = &nvarsql; /* questo solo per rimuovere gli spazi iniziali dalla macro variabile */
%put Il numero di variabili del DS è: &nvarsql; /* Stampo il risultato nel LOG */
Ecco fatto!
Spero di esserti stato utile.
Ciao
"Mi piace""Mi piace"