通过将数组命名为前缀来对变量求和

时间:2017-10-08 21:20:04

标签: arrays sas sas-macro

在下面的代码中,我有几个变量链接到一周中的某一天。我希望在同一天对所有相关值进行重新组合(例如。sales_monday1sales_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;

我的问题是:我不能在sum函数中引用我的数组,因为它是连接变量名weekDays{i}= sum(of sales_ weekDays[i]:);的一部分。 是否存在解决方案?

2 个答案:

答案 0 :(得分:0)

阵列并不像那样。你使用它们好像它们是宏变量,当它们不是时。

因此,您不能在宏变量上使用:后缀。您可以通过以下几种方式之一来完成此任务。

首先,您可以简单地将所有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中所有表中的变量列表。 (如果您在通过元数据服务器定义了大量库的服务器环境中,这可能会很慢;那么您还有其他方法可以做到这一点。)

答案 1 :(得分:0)

只需写出代码即可。一周只有7天。

monday = sum(of sales_monday:);
tuesday = sum(of sales_tuesday:);
...