SAS:在proc sql中求和

SAS:在proc sql中求和,sql,sum,sas,proc,Sql,Sum,Sas,Proc,我在一个SAS项目中工作,在这个项目中,我被要求对行进行总结。 以下是我的代码: proc sql; create table total as select sum(ans1) as sum1, sum(ans2) as sum2, sum(ans3) as sum3, sum(ans4) as sum4 from proj.scores; quit; 我的问题是有150个变量标记为ans1-ans150。有没有一种方法可

我在一个SAS项目中工作,在这个项目中,我被要求对行进行总结。 以下是我的代码:

proc sql;
  create table total as
    select 
      sum(ans1) as sum1,
      sum(ans2) as sum2,
      sum(ans3) as sum3,
      sum(ans4) as sum4
    from proj.scores;
quit;

我的问题是有150个变量标记为ans1-ans150。有没有一种方法可以将它们相加,而不必继续我的计算到150?

是的,您可以使用宏逻辑并替换1、2、3。。。带循环的行。此方法使用backstop变量,以便循环中的逗号不会在删除此变量的循环的第150次迭代中导致错误

%macro summer;

    proc sql;
        create table total (drop = backstop) as select
            %do i = 1 %to 150;
                sum(ans&i.) as sum&i.,
            %end;
            "" as backstop
            from proj.scores;
    quit;

%mend summer;

%summer;

是的,您可以使用宏逻辑并替换1、2、3。。。带循环的行。此方法使用backstop变量,以便循环中的逗号不会在删除此变量的循环的第150次迭代中导致错误

%macro summer;

    proc sql;
        create table total (drop = backstop) as select
            %do i = 1 %to 150;
                sum(ans&i.) as sum&i.,
            %end;
            "" as backstop
            from proj.scores;
    quit;

%mend summer;

%summer;

在我看来,更好的方法是这样使用宏:

data have;
input x1-x10;
datalines;
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
;;;;
run;

%macro sum_loop(prefix=, outfix=, start=1, end=);
%local i;
%do i = &start. %to &end.;  /* loop over start to end */
  sum(&prefix.&i.) as &outfix.&i.   /* the actual SQL statement */
  %if &i < &end %then %do; , %end;  /* that way you get commas after all non-last entries */
%end;
%mend sum_loop;

proc sql;
  create table total as
    select 
      %sum_loop(prefix=x,outfix=sum,start=1,end=10)
    from have
  ;
quit;

这样,宏只负责循环所需的内容。这使得它更易于重用和维护-从何处和从何处等都是分开的。。更好的做法是将内部部分拆分为自己的宏,并使用通用的looper宏,但在这里这可能有点过头了…

在我看来,更好的方法是这样使用宏:

data have;
input x1-x10;
datalines;
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
;;;;
run;

%macro sum_loop(prefix=, outfix=, start=1, end=);
%local i;
%do i = &start. %to &end.;  /* loop over start to end */
  sum(&prefix.&i.) as &outfix.&i.   /* the actual SQL statement */
  %if &i < &end %then %do; , %end;  /* that way you get commas after all non-last entries */
%end;
%mend sum_loop;

proc sql;
  create table total as
    select 
      %sum_loop(prefix=x,outfix=sum,start=1,end=10)
    from have
  ;
quit;

这样,宏只负责循环所需的内容。这使得它更易于重用和维护-从何处和从何处等都是分开的。。更好的做法是将内部部分拆分为自己的宏,并使用通用的looper宏,但在这里这可能有些过分…

我认为适当的工具将使整个过程更加容易。SQL没有处理大型变量列表的功能

proc summary;
   output out=sum sum(ans1-ans150)=sum1-sum150;
   run;

我认为适当的工具会使整个过程更容易。SQL没有处理大型变量列表的功能

proc summary;
   output out=sum sum(ans1-ans150)=sum1-sum150;
   run;

我听说9.5版的一个谣言是,如果是在开放代码中,他们将允许%do和%,这样就不需要宏包装器了。@乔,听起来这将是SAS在很长一段时间内发生的最好和最坏的事情。@RobertPenridge我的想法完全正确。我听说9.5版的一个谣言是,如果是在开放代码中,他们将允许%do和%if,不再需要像这样的宏包装器。@乔,这听起来是SAS在很长一段时间内发生的最好和最坏的事情。@RobertPenridge我的想法正是如此。除了对SAS程序严重过敏的情况外,这肯定是一条路要走除了对SAS程序有严重过敏的病例外,肯定是要走的路