Sas 将同一数据集中的多个变量追加到单个变量中

Sas 将同一数据集中的多个变量追加到单个变量中,sas,Sas,给定以下数据集: obs var1 var2 var3 1 123 456 . 2 123 . 789 3 . 456 789 如何将所有变量附加到单个变量中,同时忽略空的观察值(用“.”表示) 所需输出: obs var4 1 123 2 123 3 456 4 456 5 789 6 789 数据步骤: data have; input var1 var2 var3; cards; 123 456 . 12

给定以下数据集:

obs var1 var2 var3
1   123  456  .
2   123  .    789
3   .    456  789
如何将所有变量附加到单个变量中,同时忽略空的观察值(用“.”表示)

所需输出:

obs var4
1   123
2   123
3   456
4   456
5   789
6   789
数据步骤:

data have;
input
var1   var2   var3; cards;
123    456    .   
123    .      789 
.      456    789 
;run;

不知道为什么您将中的数字读取为char,但如果我更改为num,则可以这样做:

data have;
  input var1 var2 var3;
  cards;
123    456    .   
123    .      789 
.      456    789 
;run;
data want (keep=var4);
  set have;
  var4=var1;if var4 ne . then output;
  var4=var2;if var4 ne . then output;
  var4=var3;if var4 ne . then output;
run;

好的,假设您有一个包含值的文件,并且您不知道每行中有多少个变量。首先,我需要创建一个示例文本文件:

filename x temp;
data _nulL_;
  file x;
  put "123    456    .   ";
  put "123    .      789 ";
  put ".      456    789 ";
run;
然后我需要读取第一行并计算变量的数量:

data _null_;
  infile x;
  input;
  call symputx("number_of_variables",put(countw(_infile_," ","c"),best.));
  stop;
run;
%put &number_of_variables;
%macro doit();
data have;
  infile x;
  input
  %do i=1 %to &number_of_variables;
    var&i
  %end;
  ;
run;
data want (keep=var%eval(&number_of_variables + 1));
  set have;
  %do i=1 %to &number_of_variables;
    var%eval(&number_of_variables + 1)=var&i;
    if var%eval(&number_of_variables + 1) ne . then output;
  %end;
run;
%mend;
%doit;
现在我可以动态读取变量:

data _null_;
  infile x;
  input;
  call symputx("number_of_variables",put(countw(_infile_," ","c"),best.));
  stop;
run;
%put &number_of_variables;
%macro doit();
data have;
  infile x;
  input
  %do i=1 %to &number_of_variables;
    var&i
  %end;
  ;
run;
data want (keep=var%eval(&number_of_variables + 1));
  set have;
  %do i=1 %to &number_of_variables;
    var%eval(&number_of_variables + 1)=var&i;
    if var%eval(&number_of_variables + 1) ne . then output;
  %end;
run;
%mend;
%doit;

您可以使用
proc transpose
来执行此操作,但有一个技巧。在进行转置之前,您需要向每一行追加一个唯一标识符

我采集了@Stig的样本数据,并添加了观察编号,用作唯一标识符:

data have;
  input var1 var2 var3;
  x = _n_;  * ADDING A UNIQUE IDENTIFIER TO EVERY ROW;
  cards;
123    456    .   
123    .      789 
.      456    789 
;run;
然后就是运行proc transpose的简单例子:

proc transpose data=have out=xx;
  by x;
run;
最后,删除col1缺失的任何结果,并添加观察编号:

data want;
  obs = _n_;
  set xx (keep=col1);
  where col1 ne .;
run;

由于顺序并不重要,因此可以使用数组一步完成。当数据步骤在每一行中移动时,数组使变量值能够存储在内存中,因此您可以循环遍历它们。我对它进行了设置,以便每次找到一个非缺失值时,都将其输出到新变量

在创建数组时,我将其设置为var1--var3,双破折号表示var1和var3之间的所有变量。如果实数变量的编号方式相同,则可以使用var1-var3,这意味着两个变量之间的所有序列号

data have;
input var1 var2 var3; 
datalines;
123 456 .
123 . 789
. 456 789
;
run;

data want;
set have;
array allnums var1--var3;
do i = 1 to dim(allnums);
    if not missing(allnums{i}) then do;
    var4 = allnums{i};
    output;
    end;
end;
drop var1--var3 i;
run;

我更倾向于一个动态的解决方案,比如说在一个有99个变量的例子中,一个人不需要重复同样的代码99次输出数据集的顺序重要吗?@keith输出的顺序不重要。非常感谢。