基于另一个数组的 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;
我有以下格式的数据:
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;