Proc SQL присваивание пропущенных значений
Если я запускаю запрос, который выдает ноль строк, я все же хочу, чтобы набор данных SAS создавался с одной строкой, в которой были назначены все столбцы с пропущенными значениями.
Я нашел способ сделать это, используя отдельный шаг данных:
%let dsid = %sysfunc (open(myfile));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid = %sysfunc (close(&dsid));
data _null_;
if &anyobs=0 then do;
call execute('data work.myfile; call missing(col1, col2, col3); run;');
end;
Это прекрасно работает, но мне было интересно, если есть способ назначить пропущенные для каждого столбца в Proc SQL?
Спасибо Дэн
2 ответа
Допустим, вы выполнили это:
proc sql;
create table class as
select * from sashelp.class
where age=19;
quit;
Тогда вы можете просто сделать это:
%macro ifMissingRow(data=);
%let dsid = %sysfunc (open(&data.));
%let anyobs = %sysfunc (attrn(&dsid,ANY));
%let dsid = %sysfunc (close(&dsid));
%if &anyobs=0 %then %do;
data &data.;
output;
set &data.;
run;
%end;
%mend ifmissingRow;
%ifMissingRow(data=class);
Выход перед установкой, чтобы получить строку до того, как SET останавливает шаг данных с 0 строкой (h/t Tom для указателя).
Вот простой метод с использованием NOBS=
вариант SET
чтобы убедиться, что в вашем наборе данных есть хотя бы одно наблюдение.
data want ;
if 0=_nobs then output;
set want nobs=_nobs;
run;
Обратите внимание, что если набор данных большой и вам не нужно перезаписывать данные, вы можете использовать какой-либо метод для условного создания шага данных. Например, вы можете протестировать автоматическую макропеременную SQLOBS
и если это 0, то генерировать шаг данных. В этом случае нет необходимости проверять нобов, поскольку вы уже это сделали. Также вы можете использовать автоматическую макропеременную SYSLAST
вместо жесткого кодирования имени набора данных. Вы можете использовать CALL EXECUTE для этого, но вы также можете просто использовать IFC()
функция.
%sysfunc(dequote(
%sysfunc(ifc(0=&sqlobs,'data &syslast;output;set &syslast;run;',''))
))
Возможно, лучше всего использовать MODIFY
заявление и условно запустить OUTPUT
заявление. Вы можете проверить SQLOBS
макропеременная.
data &syslast ;
if &sqlobs=0 then output;
modify &syslast ;
stop;
run;
или вы могли бы использовать NOBS=
Опция MODIFY оператор.
data &syslast ;
if 0=_nobs then output;
modify &syslast nobs=_nobs;
stop;
run;
Все SQL решения
Если вам известно хотя бы одно из имен переменных, вы можете использовать оператор SQL insert.
insert into &syslast (varname) values (null);
Таким образом, вы можете создать простой макрос, который принимает имя набора данных, количество наблюдений и имя переменной в качестве входных данных.
%macro ifzeronull(dsn,nobs,avar);
%if &nobs=0 %then %do;
insert into &dsn (&avar) values (null);
%end;
%mend ;
Тогда вы можете остаться в том же вызове PROC SQL и условно добавить наблюдение.
proc sql;
create table want as
select * from sashelp.class
where age=19
;
%ifzeronull(&syslast,&sqlobs,name)
quit;