当变量只用后缀区分时,如何在freq表中编写一个简明的变量列表?

时间:2017-11-22 16:59:48

标签: sas

我有一个数据集,其中包含一些名为sx的变量,x = 1到 n

是否可以编写freq,其结果如下:

proc freq data=prova;
table s1 * s2 * s3 * ... * sn /list missing;
run;

但没有列出变量的所有名称?

我想要这样的输出:

S1  S2  S3  S4  Frequency
A                  10
A   E             100
A   E   J   F     300
B                  10
B   E             100
B   E   J   F     300

但是有这样的结构(当然,这是发明的):

proc freq data=prova;
table s1:sn /list missing;
run;

3 个答案:

答案 0 :(得分:2)

为什么不直接使用PROC SUMMARY? 以下是使用SASHELP.CARS中的两个变量的示例 所以这是PROC FREQ代码。

proc freq data=sashelp.cars;
  where make in: ('A','B');
  tables make*type / list;
run;

以下是使用PROC SUMMARY

获取计数的方法
proc summary missing nway data=sashelp.cars ;
  where make in: ('A','B');
  class make type ;
  output out=want;
run;
proc print data=want ;
run;

如果您需要计算百分比,则可以使用WAYS语句来获取整体和单个细胞计数。然后添加一个数据步骤来计算百分比。

proc summary missing data=sashelp.cars ;
  where make in: ('A','B');
  class make type ;
  ways 0 2 ;
  output out=want;
run;
data want ;
  set want ;
  retain total;
  if _type_=0 then total=_freq_;
  percent=100*_freq_/total;
run;

因此,如果你有10个变量,你可以使用

ways 0 10 ;
class s1-s10 ;

答案 1 :(得分:1)

如果您只想构建字符串“S1 * S2 * ...”,则可以使用DO循环或宏%DO循环并将结果放入宏变量中。

data _null_;
  length namelist $200;
  do i=1 to 10;
    namelist=catx('*',namelist,cats('S',i));
  end;
  call symputx('namelist',namelist);
run;

但是这里有一个简单的方法可以从任何变量列表中创建这样一个宏变量,而不仅仅是那些带有数字后缀的变量。

首先将变量名称放入数据集中。如果您使用OBS = 0数据集选项,PROC TRANSPOSE是一个很好的方法,这样您只能获得_NAME_列。

proc transpose data=have(obs=0) ;
  var s1-s10 ;
run;

然后使用PROC SQL将名称填充到宏变量中。

proc sql noprint;
  select _name_
    into :namelist separated by '*'
    from &syslast
  ;
quit;

然后你可以在TABLES语句中使用宏变量。

proc freq data=have ;
  tables &namelist / list missing ;
run;

答案 2 :(得分:0)

汽车':

简而言之,没有。没有用于指定跨维度的变量列表的快捷语法 很长一段时间,是的 - 如果你创建一个等价交叉的代理变量。

讨论

样本数据生成器:

%macro have(top=5);
  %local index;
  data have;
    %do index = 1 %to ⊤
    do s&index = 1 to 2+ceil(3*ranuni(123));
    %end;
    array V s:;

    do _n_ = 1 to 5*ranuni(123);
      x = ceil(100*ranuni(123));

      if ranuni(123) < 0.1 then do;
        ix = ceil(&top*ranuni(123));
        h = V(ix);
        V(ix) = .;
        output;
        V(ix) = h;
      end;
      else
        output;
    end;

    %do index = 1 %to &top;
    end;
    %end;
  run;
%mend;

%have;

您可能已经注意到table s:每个s *变量创建了一个freq。 例如:

title "One table per variable";
proc freq data=have;
  tables s: / list missing ;
run;

没有用于指定跨越维度的变量列表的快捷语法。

注意:如果指定out =,则输出数据集中的列名将是该级别中的最后一个变量。因此,对于上面,out = table将有一个列“s5”,但包含对应于每个s1到s5的组合的计数。

在每个维度级别,您可以使用变量列表,如level1 * (sublev:) * leaf中所示。对于out = data,同样需要注意。

现在,通过所有s *变量离散地重新考虑原始请求(无快捷方式):

title "1 table - 5 columns of crossings";
proc freq data=have;
  tables s1*s2*s3*s4*s5 / list missing out=outEach;
run;

并且,与数据步骤视图使用变量列表计算与上面报告的离散组合相对应的代理值时发生的情况进行比较。

data haveV / view=haveV;
  set have;
  crossing = catx(' * ', of s:);  * concatenation of all the s variables;
  keep crossing;
run;

title "1 table - 1 column of concatenated crossings";
proc freq data=haveV;
  tables crossing / list missing out=outCat;
run;

使用COMPARE进行现实检查,我不相信眼球。如果零行有差异(每noequal)则out =数据集具有相同的计数。

proc compare noprint base=outEach compare=outCat out=diffs outnoequal;
  var count;
run;
----- Log -----
NOTE: There were 31 observations read from the data set WORK.OUTEACH.
NOTE: There were 31 observations read from the data set WORK.OUTCAT.
NOTE: The data set WORK.DIFFS has 0 observations and 3 variables.
NOTE: PROCEDURE COMPARE used (Total process time)