Как определить, сколько наблюдений в наборе данных (или, если он пуст), в SAS?

Интересно, есть ли способ определить, является ли набор данных пустым, то есть он не имеет наблюдений. Или в другой поговорке, как получить количество наблюдений в конкретном наборе данных.

Так что я могу написать оператор If, чтобы установить некоторые условия.

Благодарю.

7 ответов

Решение

Это легко с PROC SQL. Сделайте подсчет и поместите результаты в макропеременную.

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

Есть много разных способов, я склонен использовать макро-функцию с open() а также attrn(), Ниже приведен простой пример, который прекрасно работает большую часть времени. Если вы собираетесь работать с представлениями данных или более сложными ситуациями, такими как набор данных с записями, помеченными для удаления или активными предложениями where, то вам может потребоваться более надежная логика.

%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);

Вот более полный пример, о котором говорил @cmjohns. Он вернет 0, если он пустой, -1, если он отсутствует, и имеет опции для обработки удаленных наблюдений и предложений where (обратите внимание, что использование выражения where может заставить макрос долго работать с очень большими наборами данных).

Примечания по использованию:

Этот макрос вернет количество наблюдений в наборе данных. Если набор данных не существует, то будет возвращено -1. Я не рекомендовал бы это для использования с именами библиотек ODBC, используйте это только против таблиц SAS.

Параметры:

  • iDs - The libname.dataset что вы хотите проверить.
  • iWhereClause (Необязательно) - пункт где применяется
  • iNobsType (необязательно) - либо NOBS ИЛИ ЖЕ NLOBSF, См. SASV9 документацию для описания.

Определение макроса:

%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;

Пример использования:

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

Результаты

19
12
-1

Монтаж

Я рекомендую настроить библиотеку SAS для автоматического вызова и поместить этот макрос в место вашего автоматического вызова.

Proc sql не эффективен, когда у нас большой набор данных. Хотя использование ATTRN является хорошим методом, но это может быть достигнуто в рамках базового sas, вот эффективное решение, которое может дать количество obs даже миллиардов строк, просто читая одну строку:

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

Я думаю, что я пытаюсь заново изобрести колесо с таким количеством ответов. Но я вижу некоторые другие методы, которые пытаются сосчитать из фактического набора данных - это может занять много времени для огромных наборов данных. Вот более эффективный метод:

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

Немного другой подход:

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

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

Это даст вам набор данных с одним наблюдением; переменная nobs имеет значение количества наблюдений в наборе данных, даже если оно равно 0.

Уловка производит вывод, даже когда набор данных пуст.

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;

Приведенный выше код является самым простым способом, который я нашел для получения количества наблюдений, даже когда набор данных пуст. Я слышал, что NOBS может быть сложным, но вышеописанное может работать для простых приложений.

Другие вопросы по тегам