通过以数组作为前缀命名变量来求和变量

Summing variable by naming them with arrays as prefix

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

我的问题是:我无法在求和函数中引用我的数组,因为它是串联变量名称的一部分 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:);
...