Sas 在观测值为0的数据集上使用VTYPE

Sas 在观测值为0的数据集上使用VTYPE,sas,Sas,在观测值为0的数据集上使用VTYPE时,我没有获得所需的信息 这里是MWE: 创建包含1个变量和1个观察值的简单集合 data fullset; myvar=1; run; 创建另一个具有相同1个变量和0个观察值的集合 data emptyset; set fullset; stop; run; 制作一个宏,打开集合,检查vtype并将其打印到日志 %macro mwe(inset); %local TYPE; data _NULL_; set &inset.; CALL SY

在观测值为0的数据集上使用VTYPE时,我没有获得所需的信息

这里是MWE:

创建包含1个变量和1个观察值的简单集合

data fullset;
myvar=1;
run;
创建另一个具有相同1个变量和0个观察值的集合

data emptyset;
set fullset;
stop;
run;
制作一个宏,打开集合,检查vtype并将其打印到日志

%macro mwe(inset);  
%local TYPE;

data _NULL_;
set &inset.;
CALL SYMPUT("TYPE", VTYPE(myvar));
put TYPE;
stop;
run;

%put &=TYPE.;
%mend mwe;
在现场进行观察时,一切正常:

%mwe(fullset);
TYPE=N
但当使用空集运行时,不会分配类型

%mwe(emptyset);
TYPE=
我想原因是没有处理代码行,因为集合没有观察值。有什么解决办法吗


注意:对于这样一个简单的任务来说,使用proc内容并解析结果表肯定是一种过分的做法

您的问题不在于
vtype()
,而在于数据步骤如何处理空数据集

当set语句尝试提取行但失败时,数据步骤立即终止。这可能很有用-例如,当您不希望它在数据集中的最后一行过去之后执行操作时。但在这种情况下,它就没那么有用了。您的数据步骤在set语句后立即终止,这意味着您的
调用将永远不会发生

但是,您可以利用另一个优势:SAS甚至在编译过程中
设置之前就可以愉快地创建所有元数据

%macro mwe(inset);  
%local TYPE;

data _NULL_;
CALL SYMPUT("TYPE", VTYPE(myvar));
set &inset.;
stop;
run;

%put &=TYPE.;
%mend mwe;
请注意,我将
call-symput
移到了
set
之前。是的,
vtype()
即使在设置之前也可以正常工作-即使在数据步骤中发生任何事情之前,变量仍然在PDV中定义


(我还去掉了虚假的
put
语句,它永远不会做任何事情,因为在任何一个版本中都没有创建
TYPE
变量。)

您的问题不在于
vtype()
,而在于数据步骤如何处理空数据集

当set语句尝试提取行但失败时,数据步骤立即终止。这可能很有用-例如,当您不希望它在数据集中的最后一行过去之后执行操作时。但在这种情况下,它就没那么有用了。您的数据步骤在set语句后立即终止,这意味着您的
调用将永远不会发生

但是,您可以利用另一个优势:SAS甚至在编译过程中
设置之前就可以愉快地创建所有元数据

%macro mwe(inset);  
%local TYPE;

data _NULL_;
CALL SYMPUT("TYPE", VTYPE(myvar));
set &inset.;
stop;
run;

%put &=TYPE.;
%mend mwe;
请注意,我将
call-symput
移到了
set
之前。是的,
vtype()
即使在设置之前也可以正常工作-即使在数据步骤中发生任何事情之前,变量仍然在PDV中定义


(我还去掉了虚假的
put
语句,该语句永远不会做任何事情,因为在任何版本中都没有创建
TYPE
变量。)

另一种方法是使用
vartype
函数,它不需要set语句,与
vtype
函数不同,它可以在数据步骤之外的纯宏代码中使用(无需诉诸
dosubl
等)

实际上,这意味着您可以使用
vartype
制作
vtype
的函数式宏版本,如下所示:

%macro vtype(ds,var);
  %local dsid varnum rc vartype;
  %let dsid = %sysfunc(open(&ds));
  %let varnum = %sysfunc(varnum(&dsid,&var));
  %let vartype = %sysfunc(vartype(&dsid,&varnum));
  %let rc = %sysfunc(close(&dsid));
  &vartype
%mend vtype;

/*Example*/
%put %vtype(emptyset,myvar);

/*Output*/
N

另一种方法是使用
vartype
函数,该函数不需要set语句,与
vtype
不同,它可以在数据步骤之外的纯宏代码中使用(无需诉诸
dosubl
等)

实际上,这意味着您可以使用
vartype
制作
vtype
的函数式宏版本,如下所示:

%macro vtype(ds,var);
  %local dsid varnum rc vartype;
  %let dsid = %sysfunc(open(&ds));
  %let varnum = %sysfunc(varnum(&dsid,&var));
  %let vartype = %sysfunc(vartype(&dsid,&varnum));
  %let rc = %sysfunc(close(&dsid));
  &vartype
%mend vtype;

/*Example*/
%put %vtype(emptyset,myvar);

/*Output*/
N

同意如果你想得到一个宏变量,这是一个更好的选择。同意如果你想得到一个宏变量,这是一个更好的选择。