总结一个包含未知数量变量的表?

时间:2014-06-10 21:05:49

标签: sas

我对SAS很新。我过去曾经用过它,但我真的很生气。

我有一张看起来像这样的表:

Key   Group1 Metric1  Group2  Metric2  Group3 Metric3
1                .       r       20             .
1                .                .        t     3

对于几个独特的键。 我希望所有内容都显示在一行上,所以它看起来像。

Key   Group1 Metric1  Group2  Metric2  Group3 Metric3
1                .       r       20       t      3

另一个问题是我不知道我将拥有多少组和公制列(虽然我总是有相同的数字)。

我不确定如何处理这个问题。我能够得到一个列名列表并在宏中使用它们,我只是不确定我需要使用什么proc或datastep函数来解决所有问题。对于任何建议,我都会非常感激。

2 个答案:

答案 0 :(得分:3)

有一种非常简单的方法可以使用一个很好的技巧来做到这一点。我之前已经回答了类似的问题,请参阅here其中一个问题。这应该达到你想要的目的。

答案 1 :(得分:1)

您可以使用2个临时数组(一个用于字符变量,另一个用于数字),并相应地填充非空值。当您到达last.key时,可以将临时数组加载回源变量。

如果您事先知道字符变量的最大长度,则可以对其进行硬编码,但如果不知道,则可以动态确定它。

这假设对于每个键,每个变量仅填充一次。否则,它将获取它在每个键中为特定变量看到的最后一个值。

%LET LIB    = work ;
%LET DSN    = mydata ;
%LET KEYVAR = key ;

/* Get column name/type/max length */
proc sql ;
  /* Numerics */
  select name, count(name) into :NVARNAMES separated by ' ', :NVARNUM
  from dictionary.columns
  where libname = upcase("&LIB")
    and memname = upcase("&DSN")
    and name   ^= upcase("&KEYVAR")
    and type    = 'num' ;

  /* Characters */
  select name, count(name), max(length) into :CVARNAMES separated by ' ', :CVARNUM, :CVARLEN
  from dictionary.columns
  where libname = upcase("&LIB")
    and memname = upcase("&DSN")
    and name   ^= upcase("&KEYVAR")
    and type    = 'char' ;
quit ;

data flatten ;
  set &LIB..&DSN ;
  by &KEYVAR ;

  array  n{&NVARNUM} &NVARNAMES ;
  array nt{&NVARNUM} _TEMPORARY_ ;

  array  c{&CVARNUM} &CVARNAMES ;
  array ct{&CVARNUM} $&CVARLEN.. _TEMPORARY_ ;

  retain nt ct ;
  if first.&KEYVAR then do ;
    call missing(of nt{*}, of ct{*}) ;
  end ;

  /* Load non-missing numeric values into temporary array */
  do i = 1 to dim(n) ;
    if not missing(n{i}) then nt{i} = n{i} ;
  end ;

  /* Load non-missing character values into temporary array */
  do i = 1 to dim(c) ;
    if not missing(c{i}) then ct{i} = c{i} ;
  end ;

  if last.&KEYVAR then do ;
    /* Load numeric back into original variables */
    call missing(of n{*}) ;
    do i = 1 to dim(n) ;
      n{i} = nt{i} ;
    end ;

    /* Load character back into original variables */
    call missing(of c{*}) ;
    do i = 1 to dim(c) ;
      c{i} = ct{i} ;
    end ;
    output ;
  end ;

  drop i ;
run ;