Sas 用未知数量的变量求和一个表?

Sas 用未知数量的变量求和一个表?,sas,Sas,我是SAS的新手。我过去用过一点,但我真的生锈了 我有一张像这样的桌子: Key Group1 Metric1 Group2 Metric2 Group3 Metric3 1 . r 20 . 1 . . t 3 对于几个唯一的键。 我希望所有内容都显示在一行上,使其看起来像 Key Group1 Metric1 Gro

我是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函数来折叠所有内容。如果有任何建议,我将不胜感激。

您可以使用两个临时数组,一个用于字符变量,另一个用于数字,并相应地用非空值填充它们。当到达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 ;
您可以使用两个临时数组,一个用于字符变量,另一个用于数字变量,并相应地用非空值填充它们。当到达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 ;
有一个非常简单的方法可以使用一个好的技巧来实现这一点。我以前也回答过类似的问题,请看其中一个。这应该能达到你想要的效果。

有一个非常简单的方法,使用一个好的技巧。我以前也回答过类似的问题,请看其中一个。这应该能实现你所追求的目标