(SAS)如何用其他变量的值命名列

(SAS) how to name the column with the value of other variable

给定的数据集 'temp' 看起来像这样..

index code1 code2 code3
A P1 P2 P3
B P1 P3 P4
C P2 P4 N1

然后我想制作这样的新数据集

index P1 P2 P3 P4 n1
A 1 1 1 0 0
B 1 0 1 1 0
C 0 1 0 1 1

我的代码在这里...

%macro freq;
%do i = 1 %to 3;
    %do j = 1 %to 5;
    if substr(code&i.,1,1) = "P" then
        if input(substr(code&i.,2,1),1.) = &j. then p&j. = 1;
    if substr(code&i.,1,1) = "N" then
        if input(substr(code&i.,2,1),1.) = &j. then n&j. = 1;
    %end;
%end;
%mend;

但这并不酷:(

如何创建一个名称为变量值(代码 1、代码 2、...)的新列?

还有其他简单的方法吗?

怎么样

data have;
input (index code1 code2 code3)($);
datalines;
A P1 P2 P3
B P1 P3 P4
C P2 P4 N1
;

data temp;
   set have;
   array c code:;
   do over c;
      v = c;
      d = 1;
      output;
   end;
run;

proc transpose data = temp out = want(drop = _:);
   by index;
   id v;
   var d;
run;

您可以在 DATA 步骤中使用 ARRAYVNAME 函数,无需宏即可实现此目的。

data want;
  set have;
  /* Initialize flag variables. */
  length P1-P4 3 N1 3;
  /* Define arrays. */
  array code [*] code1-code3;
  array flags [*] P1-P4 N1;
  /* Loop over the arrays. */
  do i = 1 to dim(flags);
    flags[i] = 0;
    do j = 1 to dim(code);
      if vname(flags[i]) = code[j] then flags[i] = 1;
    end;
  end;
  keep index P1-P4 N1;
run;

将值转换为变量名的最简单方法是通过 PROC TRANSPOSE。因此,首先将您的宽数据集转换为高数据集。您可以使用 PROC TRANSPOSE 来做到这一点,但是要使您的目标数据集 PROC TRANSPOSE 需要一些数字变量来转置。那么为什么不使用数据步骤来制作 tall 数据集并包含一个设置为 1 的数字变量。

PROC TRANSPOSE 步骤将为您提供一个数据集,其中新变量的值为 1 或缺失值。您可以使用 PROC STDIZE 将缺失值更改为零。

data have; 
  input index $ (code1-code3) (:.) ;
cards;
A P1 P2 P3
B P1 P3 P4
C P2 P4 N1
;

data tall;
  set have ;
  array code code1-code3;
  length _name_  dummy 8;
  retain dummy 1;
  do column=1 to dim(code);
     _name_=code[column];
     if not missing(_name_) then output;
  end;
run;

proc transpose data=tall out=want(drop=_name_);
  by index ;
  id _name_;
  var dummy;
run;

proc stdize reponly missing=0 data=want ;
  var _numeric_;
run;

还有一个选择:

proc transpose data=have out=long;
    by index;
    var code:;
run;

data long2;
    set long;
    value = 1;
run;

proc transpose data=long2 out=wide;
    by index;
    id col1;
    var value;
run;

/* Convert missing to zeroes */
data want;
    set wide;
    array vars _NUMERIC_;

    do over vars;
        if(vars = .) then vars = 0;
    end;
    
    drop _NAME_;
run;

输出:

index   P1  P2  P3  P4  N1
A       1   1   1   0   0
B       1   0   1   1   0
C       0   1   0   1   1