基于另一个数组的 SAS 数组变量名称

SAS Array Variable Name Based on Another Array

我有以下格式的数据:

data have;
input id rtl_apples rtl_oranges rtl_berries;
    datalines;
1 50 60 10
2 10 30 80
3 40 8 1
;

我正在尝试创建新变量来表示 RTL 变量之和的百分比,PCT_APPLES, PCT_ORANGES, PCT_BERRIES。问题是我在宏中执行此操作,因此 RTL 变量的名称和数量随每次迭代而变化,因此需要动态生成新变量名称。

这个数据步骤基本上得到了我需要的,但是新变量的格式是 PCT1, PCT2, PCTn 格式,所以很难知道 PCT 对应的是哪个 RTL 变量。

data want;
set have;
array rtls[*] rtl_:;
total_sales = sum(of rtl_:);
call symput("dim",dim(rtls));
array pct[&dim.];
do i=1 to dim(rtls);
    pct[i] = rtls[i] / total_sales;
end;
drop i;
run;

我也尝试过使用宏变量创建新的变量名,但只创建了数组中的最后一个变量。在这种情况下,PCT_BERRIES.

data want;
set have;
array rtls[*] rtl_:;
total_sales = sum(of rtl_:);
do i=1 to dim(rtls);
    var_name = compress(tranwrd(upcase(vname(rtls[i])),'RTL','PCT'));
    call symput("var_name",var_name);
    &var_name. = rtls[i] / total_sales;
end;
drop i var_name;
run;

我觉得我把这个复杂化了,所以任何帮助将不胜感激。

您不能在数据步骤执行时创建变量。该程序使用 PROC TRANSPOSE 使用 RTL_ 变量“重命名”PCT_ 创建新数据。

data have;
   input id rtl_apples rtl_oranges rtl_berries;
   datalines;
1 50 60 10
2 10 30 80
3 40 8 1
;;;;
   run;
proc transpose data=have(obs=0) out=names;
   var rtl_:;
   run;
data pct;
   set names;
   _name_ = transtrn(_name_,'rtl_','PCT_');
   y = .;
   run;
proc transpose data=pct out=pct2;
   id _name_;
   var y;
   run;
data want;
   set have;
   if 0 then set pct2(drop=_name_);
   array _rtl[*] rtl_:;
   array _pct[*] pct_:;
   call missing(of _pct[*]);
   total = sum(of _rtl[*]);
   do i = 1 to dim(_rtl);
      _pct[i] = _rtl[i]/total*1e2;
      end;
   drop i;
   run;

proc print;
   run;

如果数据中已有名称列表,则使用该列表创建数组所需的名称。

proc sql noprint;
  select distinct cats('RTL_',name),cats('PCT_',name)
  into :rtl_list separated by ' '
     , :pct_list separated by ' '
  from dataset_with_names
  ;
quit;

data want;
  set have;
  array rtls &rtl_list;
  array pcts &pct_list;
  total_sales = sum(of rtls[*]);
  do index=1 to dim(rtls);
    pcts[index] = rtls[index] / total_sales;
  end;
  drop index ;
run;

您可能只想报告行百分比

  proc transpose data=&data out=&data.T;
    by id;
    var rtl_:;
  run;

  proc tabulate data=&data.T;
    class id _name_;
    var col1;
    table 
      id=''
    , _name_='Result'*col1=''*sum=''
      _name_='Percent'*col1=''*rowpctsum=''
    / nocellmerge;
  run;