1
data myout ;
set braw.accounts end = eof;
     fname = "BANK_ACCT"; 
        retain countmissing cm2 0;
        if missing(fname) = 0 then countmissing = countmissing+1; 
        if missing(BANK_ACCT) = 0 then cm2 = cm2 +1; 

    if eof then output; 
    keep fname countmissing cm2;

run; 

(^ 不知道为什么不缩进)。

所以我想做的是从字典中读取变量的名称,然后对每个变量进行分析,计算缺失的数量。

问题是当我将 fname 传递给 missing() 时,它正在寻找一个名为“fname”而不是“BANK_ACCT”的变量。在传递之前如何告诉它解决?

4

1 回答 1

1

有几种方法可以处理这个问题:

1) 构造一个包含变量名称的宏变量,然后定义一个数组。您发布的上一个问题将是一个很好的起点。像这样的东西:

proc sql;
 select name into :varlist separated by ' ' from dictionary.columns 
 where memname='DATASET' and libname='LIBRARY'
 and <conditions defining which columns you want>;
quit;

data myout ;
set braw.accounts end = eof;
    array fname &varlist;
    do _t = 1 to dim(fname); 
        if missing(fname[_t]) = 0 then countmissing+1; 
        if missing(BANK_ACCT) = 0 then cm2 +1; 
    end;
    if eof then output; 
    keep fname countmissing cm2;  
run; 

(还引入了一个新概念——+1;自动做retain var 0; bit)

顺便说一句,您可能会发现使用 CALL SYMPUT 将 countmissing 放入宏变量而不是输出一行(取决于您使用它的目的)很有用。

2) 与 1 类似,但您可以创建一个包含所有变量的数组,或所有数值变量,或从一个点到另一个点的所有变量。

array fname _all_; *will only work if all variables are same type;
array fname _numeric_;
array fname var_first -- var_last; *all variables in order from left to right from var_first to var_last;

3)对“标准化”数据集进行操作,因此数据集只有两个(或几个)变量——“varname”和“value”。这需要一些(重要的)工作来创建,因此仅在某些情况下有用。

4)使用数据集以外的其他方法来解决这个问题。例如,PROC FREQ 或 PROC TABULATE 可以轻松地为您提供每个变量的缺失值数量(使用缺失选项)。

于 2013-01-29T22:37:51.067 回答