通过以数组作为前缀命名变量来求和变量
Summing variable by naming them with arrays as prefix
在下面的代码中,我有几个变量链接到一周中的某一天。我希望按同一天所有相关值的总和重新组合( 例如 sales_monday1
和 sales_monday2
在名为 Monday 的新变量中求和)。
为此,我想使用一个数组:
data test;
input sales_monday1 sales_monday2 sales_tuesday sales_wednesday;
datalines;
1 1 2 .
2 5 6 .
3 20 . 1
;
run;
Data test;
ARRAY weekDays{*} Monday Tuesday Wednesday Thursday Friday Saturday Sunday;
set test;
do i=1 to DIM(weekDays);
weekDays{i}= sum(of sales_ weekDays[i]:);
end;
drop i;
run;
我的问题是:我无法在求和函数中引用我的数组,因为它是串联变量名称的一部分 weekDays{i}= sum(of sales_ weekDays[i]:);
。
是否存在解决该问题的方法?
数组不是那样工作的。您将它们当作宏变量来使用,而实际上它们不是。
因此,您不能在宏变量上使用 :
后缀。您可以通过以下几种方式之一来执行此操作。
首先,您可以简单地将所有 sales
变量放入一个数组中,然后以您喜欢的顺序循环遍历这两个变量,然后使用 VNAME
和一些帮助来比较变量名称。
Data test_sum;
ARRAY weekDays{*} Monday Tuesday Wednesday Thursday Friday Saturday Sunday;
set test;
array sales sales_:;
do i=1 to DIM(weekDays);
do j = 1 to dim(sales);
if upcase(compress(scan(vname(sales[j]),2,'_'),,'ka')) = upcase(vname(weekdays[i]))
then weekdays[i] = sum(weekdays[i],sales[j]);
end;
end;
drop i j;
run;
当你进行大量不必要的比较时,它的效率非常低,所以如果你有一个大数据集,这可能不适合你。对于小型数据集,这可能是正确答案。
对于大型数据集,您应该改用宏语言来执行此操作。
%macro sum_weekday(name=);
%let weekday = %sysfunc(compress(%sysfunc(scan(&name.,2,_)),,ka));
&weekday. = sum(&weekday., &name.);
%mend sum_weekday;
proc sql;
select cats('%sum_weekday(name=',name,')') into :sumlist separated by ' '
from dictionary.columns
where memname='TEST' and libname='WORK'
;
quit;
data test_macro;
set test;
&sumlist;
run;
这非常有效,因为它只查看变量列表一次,而不是每行一次。基本上,它只是创建了很多语句,例如
monday = sum(monday, sales_monday1);
monday = sum(monday, sales_monday2);
tuesday= sum(tuesday,sales_tuesday);
等等,基于dictionary.columns
这是你SAS中所有表的变量列表。 (如果你在一个服务器环境中有很多通过元数据服务器定义的库,这可能会很慢;那么你有其他方法可以做到这一点。)
直接写出代码。一周只有7天。
monday = sum(of sales_monday:);
tuesday = sum(of sales_tuesday:);
...
在下面的代码中,我有几个变量链接到一周中的某一天。我希望按同一天所有相关值的总和重新组合( 例如 sales_monday1
和 sales_monday2
在名为 Monday 的新变量中求和)。
为此,我想使用一个数组:
data test;
input sales_monday1 sales_monday2 sales_tuesday sales_wednesday;
datalines;
1 1 2 .
2 5 6 .
3 20 . 1
;
run;
Data test;
ARRAY weekDays{*} Monday Tuesday Wednesday Thursday Friday Saturday Sunday;
set test;
do i=1 to DIM(weekDays);
weekDays{i}= sum(of sales_ weekDays[i]:);
end;
drop i;
run;
我的问题是:我无法在求和函数中引用我的数组,因为它是串联变量名称的一部分 weekDays{i}= sum(of sales_ weekDays[i]:);
。
是否存在解决该问题的方法?
数组不是那样工作的。您将它们当作宏变量来使用,而实际上它们不是。
因此,您不能在宏变量上使用 :
后缀。您可以通过以下几种方式之一来执行此操作。
首先,您可以简单地将所有 sales
变量放入一个数组中,然后以您喜欢的顺序循环遍历这两个变量,然后使用 VNAME
和一些帮助来比较变量名称。
Data test_sum;
ARRAY weekDays{*} Monday Tuesday Wednesday Thursday Friday Saturday Sunday;
set test;
array sales sales_:;
do i=1 to DIM(weekDays);
do j = 1 to dim(sales);
if upcase(compress(scan(vname(sales[j]),2,'_'),,'ka')) = upcase(vname(weekdays[i]))
then weekdays[i] = sum(weekdays[i],sales[j]);
end;
end;
drop i j;
run;
当你进行大量不必要的比较时,它的效率非常低,所以如果你有一个大数据集,这可能不适合你。对于小型数据集,这可能是正确答案。
对于大型数据集,您应该改用宏语言来执行此操作。
%macro sum_weekday(name=);
%let weekday = %sysfunc(compress(%sysfunc(scan(&name.,2,_)),,ka));
&weekday. = sum(&weekday., &name.);
%mend sum_weekday;
proc sql;
select cats('%sum_weekday(name=',name,')') into :sumlist separated by ' '
from dictionary.columns
where memname='TEST' and libname='WORK'
;
quit;
data test_macro;
set test;
&sumlist;
run;
这非常有效,因为它只查看变量列表一次,而不是每行一次。基本上,它只是创建了很多语句,例如
monday = sum(monday, sales_monday1);
monday = sum(monday, sales_monday2);
tuesday= sum(tuesday,sales_tuesday);
等等,基于dictionary.columns
这是你SAS中所有表的变量列表。 (如果你在一个服务器环境中有很多通过元数据服务器定义的库,这可能会很慢;那么你有其他方法可以做到这一点。)
直接写出代码。一周只有7天。
monday = sum(of sales_monday:);
tuesday = sum(of sales_tuesday:);
...