Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sas Proc sql和宏变量_Sas - Fatal编程技术网

Sas Proc sql和宏变量

Sas Proc sql和宏变量,sas,Sas,我正在尝试运行一个代码,该代码应该在考虑不同因素的情况下创建的表上运行。由于这些因素可能超过1,我决定创建一个宏%let来列出它们: %let list= factor1 factor2 ...; 我想做的是运行一段代码,使用不同的因子创建这些表。对于每个因子,我使用proc平均值和标准偏差计算,因此我应该在proc平均值为每个因子创建的表中有变量&list.\u mean and&list.\u stddev。这个表被标记为t2,我需要连接到另一个表t1。从t1开始,我考虑所有变量 因此,我

我正在尝试运行一个代码,该代码应该在考虑不同因素的情况下创建的表上运行。由于这些因素可能超过1,我决定创建一个宏%let来列出它们:

%let list= factor1 factor2 ...;
我想做的是运行一段代码,使用不同的因子创建这些表。对于每个因子,我使用proc平均值和标准偏差计算,因此我应该在proc平均值为每个因子创建的表中有变量&list.\u mean and&list.\u stddev。这个表被标记为t2,我需要连接到另一个表t1。从t1开始,我考虑所有变量

因此,我的主要困难在于proc sql:

proc sql;
create table new_table as
select t1.*
, t2.&list._mean as mean
, t2.&list._stddev as stddev
from table1 as t1
left join table2 as t2
on t1.time=t2.time
order by t2.&list.
quit;
这段代码返回了一个错误,我认为这是因为我考虑的是t2.factor1 factor2,即t2只适用于第一个因子,而不适用于第二个因子。 我所期望的是:

  proc sql;
    create table new_table as
    select t1.*
    , t2.factor1._mean as mean
    , t2.factor1._stddev as stddev
    from table1 as t1
    left join table2 as t2
    on t1.time=t2.time
    order by t2.factor1.
    quit;
另一个是第二因子。 更新代码:

%macro test_v1(
     _dtb
    ,_input
    ,_output
    ,_time
    ,_factor
);

data &_input.;
    set &_dtb..&_input.;
    keep &_col_period. &_factor.;
run;

proc sort data = work.&_input.
           out = &_input._1;
    by &_factor. &_time.;
run;

%put ERROR: 2

proc means data=&_input._1 nonobs mean stddev;
    class &_time.;
    var &_factor.;
    output out=&_input._n (drop=_TYPE_) mean= stddev= /autoname ;
run;

%put ERROR: 3

proc sql;
create table work.&_input._data as 
select t1.*
        ,t2.&_factor._mean as mean
        ,t2.&_factor._stddev as stddev
from &_input. as t1
left join &_input._n as t2
on t1.&_time.=t2.&_time.
order by &_factor.;
quit;

%mend test_v1;

我的问题是如何考虑多个因素,定义为宏作为一个列表,作为表的列和作为宏的输入数据,例如:%TestDATABETE,TabLeNAMEY,List. 我怀疑试图使用PROC-SQL是问题的症结所在。如果您坚持只使用普通SAS语法,那么以空格分隔的变量名列表很容易使用

因此,将您的代码稍加调整:

%macro test_v1
(_dtb    /* Input libref */
,_input  /* Input member name */
,_output /* Output dataset */
,_time   /* Class/By variable(s) */
,_factor /* Analysis variable(s) */
);

proc sort data= &_dtb..&_input. out=_temp1;
  by &_time. ;
run;

proc means data=_temp1 nonobs mean stddev;
  by &_time.;
  var &_factor.;
  output out=_temp2 (drop=_TYPE_) mean= stddev= /autoname ;
run;

data &_output. ;
  merge _temp1 _temp2 ;
  by &_time.;
run;

%mend test_v1;
然后我们可以使用SASHELP.CLASS测试它,使用性别作为时间变量,身高和体重作为分析变量

%test_v1(_dtb=sashelp,_input=class,_output=want,_time=sex,_factor=height weight);

我怀疑试图使用procsql是使问题变得困难的原因。如果您坚持只使用普通SAS语法,那么以空格分隔的变量名列表很容易使用

因此,将您的代码稍加调整:

%macro test_v1
(_dtb    /* Input libref */
,_input  /* Input member name */
,_output /* Output dataset */
,_time   /* Class/By variable(s) */
,_factor /* Analysis variable(s) */
);

proc sort data= &_dtb..&_input. out=_temp1;
  by &_time. ;
run;

proc means data=_temp1 nonobs mean stddev;
  by &_time.;
  var &_factor.;
  output out=_temp2 (drop=_TYPE_) mean= stddev= /autoname ;
run;

data &_output. ;
  merge _temp1 _temp2 ;
  by &_time.;
run;

%mend test_v1;
然后我们可以使用SASHELP.CLASS测试它,使用性别作为时间变量,身高和体重作为分析变量

%test_v1(_dtb=sashelp,_input=class,_output=want,_time=sex,_factor=height weight);

您可以尝试通过扫描因子列表将宏循环添加到宏中。它可能看起来像:

%macro test(list);
   %do i=1 to %sysfunc(countw(&list,%str( )));
      %let factorname=%scan(&list,&i,%str( ));
       /* if macro variable list equals factor1 factor2 then there would be
       two iterations in loop, i=1 factorname=factor1 and i=2 factorname=2*/
      /*your code here*/
   %end
%mend test;
更新:

%macro test(_input, _output, factors_list); %macro d; %mend d;
%do i=1 %to %sysfunc(countw(&factors_list,%str( )));
%let tfactor=%scan(&factors_list,&i,%str( ));
proc sort data = work.&_input.
           out = &_input._1;
    by &factors_list. time;
run;

proc means data=&_input._1 nonobs mean stddev;
    class time;
    var &tfactor.;
    output out=&_input._num (drop=_TYPE_) mean= stddev= /autoname ;
run;

proc sql;
   create table &_output._&tfactor as
   select t1.*
   , t2.&tfactor._mean as mean
   , t2.&tfactor._stddev as stddev
   from &_input as t1
   left join &_input._num as t2
   on t1.time=t2.time
   order by t1.&tfactor;
quit;

%end;
%mend test;

%test(have,newdata,factor1 factor2);
拥有数据集:

+------+---------+---------+
| time | factor1 | factor2 |
+------+---------+---------+
|    1 |   12345 |    1234 |
|    2 |     123 |      12 |
|    3 |       1 |      -1 |
|    4 |     -12 |    -123 |
|    5 |   -1234 |  -12345 |
|    6 |    9876 |     987 |
|    7 |      98 |       8 |
|    8 |       9 |       7 |
|    1 |    1234 |     123 |
|    2 |      12 |       1 |
|    3 |      12 |     -12 |
|    4 |    -123 |   -1234 |
|    5 |  -12345 | -123456 |
|    6 |     987 |      98 |
|    7 |       9 |      -9 |
|    8 |    1234 |    1234 |
+------+---------+---------+
新数据系数1:

+------+---------+---------+---------+--------------+
| time | factor1 | factor2 |  mean   |    stddev    |
+------+---------+---------+---------+--------------+
|    5 |  -12345 | -123456 | -6789.5 | 7856.6634458 |
|    5 |   -1234 |  -12345 | -6789.5 | 7856.6634458 |
|    4 |    -123 |   -1234 |   -67.5 | 78.488852712 |
|    4 |     -12 |    -123 |   -67.5 | 78.488852712 |
|    3 |       1 |      -1 |     6.5 | 7.7781745931 |
|    7 |       9 |      -9 |    53.5 | 62.932503526 |
|    8 |       9 |       7 |   621.5 | 866.20580695 |
|    3 |      12 |     -12 |     6.5 | 7.7781745931 |
|    2 |      12 |       1 |    67.5 | 78.488852712 |
|    7 |      98 |       8 |    53.5 | 62.932503526 |
|    2 |     123 |      12 |    67.5 | 78.488852712 |
|    6 |     987 |      98 |  5431.5 |  6285.472178 |
|    1 |    1234 |     123 |  6789.5 | 7856.6634458 |
|    8 |    1234 |    1234 |   621.5 | 866.20580695 |
|    6 |    9876 |     987 |  5431.5 |  6285.472178 |
|    1 |   12345 |    1234 |  6789.5 | 7856.6634458 |
+------+---------+---------+---------+--------------+
新数据系数2:

+------+---------+---------+----------+--------------+
| time | factor1 | factor2 |   mean   |    stddev    |
+------+---------+---------+----------+--------------+
|    5 |  -12345 | -123456 | -67900.5 | 78567.341564 |
|    5 |   -1234 |  -12345 | -67900.5 | 78567.341564 |
|    4 |    -123 |   -1234 |   -678.5 |  785.5956339 |
|    4 |     -12 |    -123 |   -678.5 |  785.5956339 |
|    3 |      12 |     -12 |     -6.5 | 7.7781745931 |
|    7 |       9 |      -9 |     -0.5 |  12.02081528 |
|    3 |       1 |      -1 |     -6.5 | 7.7781745931 |
|    2 |      12 |       1 |      6.5 | 7.7781745931 |
|    8 |       9 |       7 |    620.5 | 867.62002052 |
|    7 |      98 |       8 |     -0.5 |  12.02081528 |
|    2 |     123 |      12 |      6.5 | 7.7781745931 |
|    6 |     987 |      98 |    542.5 | 628.61792847 |
|    1 |    1234 |     123 |    678.5 |  785.5956339 |
|    6 |    9876 |     987 |    542.5 | 628.61792847 |
|    1 |   12345 |    1234 |    678.5 |  785.5956339 |
|    8 |    1234 |    1234 |    620.5 | 867.62002052 |
+------+---------+---------+----------+--------------+

您可以尝试通过扫描因子列表将宏循环添加到宏中。它可能看起来像:

%macro test(list);
   %do i=1 to %sysfunc(countw(&list,%str( )));
      %let factorname=%scan(&list,&i,%str( ));
       /* if macro variable list equals factor1 factor2 then there would be
       two iterations in loop, i=1 factorname=factor1 and i=2 factorname=2*/
      /*your code here*/
   %end
%mend test;
更新:

%macro test(_input, _output, factors_list); %macro d; %mend d;
%do i=1 %to %sysfunc(countw(&factors_list,%str( )));
%let tfactor=%scan(&factors_list,&i,%str( ));
proc sort data = work.&_input.
           out = &_input._1;
    by &factors_list. time;
run;

proc means data=&_input._1 nonobs mean stddev;
    class time;
    var &tfactor.;
    output out=&_input._num (drop=_TYPE_) mean= stddev= /autoname ;
run;

proc sql;
   create table &_output._&tfactor as
   select t1.*
   , t2.&tfactor._mean as mean
   , t2.&tfactor._stddev as stddev
   from &_input as t1
   left join &_input._num as t2
   on t1.time=t2.time
   order by t1.&tfactor;
quit;

%end;
%mend test;

%test(have,newdata,factor1 factor2);
拥有数据集:

+------+---------+---------+
| time | factor1 | factor2 |
+------+---------+---------+
|    1 |   12345 |    1234 |
|    2 |     123 |      12 |
|    3 |       1 |      -1 |
|    4 |     -12 |    -123 |
|    5 |   -1234 |  -12345 |
|    6 |    9876 |     987 |
|    7 |      98 |       8 |
|    8 |       9 |       7 |
|    1 |    1234 |     123 |
|    2 |      12 |       1 |
|    3 |      12 |     -12 |
|    4 |    -123 |   -1234 |
|    5 |  -12345 | -123456 |
|    6 |     987 |      98 |
|    7 |       9 |      -9 |
|    8 |    1234 |    1234 |
+------+---------+---------+
新数据系数1:

+------+---------+---------+---------+--------------+
| time | factor1 | factor2 |  mean   |    stddev    |
+------+---------+---------+---------+--------------+
|    5 |  -12345 | -123456 | -6789.5 | 7856.6634458 |
|    5 |   -1234 |  -12345 | -6789.5 | 7856.6634458 |
|    4 |    -123 |   -1234 |   -67.5 | 78.488852712 |
|    4 |     -12 |    -123 |   -67.5 | 78.488852712 |
|    3 |       1 |      -1 |     6.5 | 7.7781745931 |
|    7 |       9 |      -9 |    53.5 | 62.932503526 |
|    8 |       9 |       7 |   621.5 | 866.20580695 |
|    3 |      12 |     -12 |     6.5 | 7.7781745931 |
|    2 |      12 |       1 |    67.5 | 78.488852712 |
|    7 |      98 |       8 |    53.5 | 62.932503526 |
|    2 |     123 |      12 |    67.5 | 78.488852712 |
|    6 |     987 |      98 |  5431.5 |  6285.472178 |
|    1 |    1234 |     123 |  6789.5 | 7856.6634458 |
|    8 |    1234 |    1234 |   621.5 | 866.20580695 |
|    6 |    9876 |     987 |  5431.5 |  6285.472178 |
|    1 |   12345 |    1234 |  6789.5 | 7856.6634458 |
+------+---------+---------+---------+--------------+
新数据系数2:

+------+---------+---------+----------+--------------+
| time | factor1 | factor2 |   mean   |    stddev    |
+------+---------+---------+----------+--------------+
|    5 |  -12345 | -123456 | -67900.5 | 78567.341564 |
|    5 |   -1234 |  -12345 | -67900.5 | 78567.341564 |
|    4 |    -123 |   -1234 |   -678.5 |  785.5956339 |
|    4 |     -12 |    -123 |   -678.5 |  785.5956339 |
|    3 |      12 |     -12 |     -6.5 | 7.7781745931 |
|    7 |       9 |      -9 |     -0.5 |  12.02081528 |
|    3 |       1 |      -1 |     -6.5 | 7.7781745931 |
|    2 |      12 |       1 |      6.5 | 7.7781745931 |
|    8 |       9 |       7 |    620.5 | 867.62002052 |
|    7 |      98 |       8 |     -0.5 |  12.02081528 |
|    2 |     123 |      12 |      6.5 | 7.7781745931 |
|    6 |     987 |      98 |    542.5 | 628.61792847 |
|    1 |    1234 |     123 |    678.5 |  785.5956339 |
|    6 |    9876 |     987 |    542.5 | 628.61792847 |
|    1 |   12345 |    1234 |    678.5 |  785.5956339 |
|    8 |    1234 |    1234 |    620.5 | 867.62002052 |
+------+---------+---------+----------+--------------+

即使您修复了语法错误,您的计划也无法运行。您不能将FACTOR1和FACTOR2都重命名为同一个名称。我认为您可以使用一步过程排序,而不是两步数据+过程排序:过程排序数据=have1keep=time FACTOR1 out=have3\u 1;按系数1计算;跑代替数据2;设置have1;保持时间系数1;跑proc sort data=have2 out=have2_1;按系数1计算;跑为什么宏引用一个完全未定义的宏变量,col\u period?为什么按因子变量而不是按时间排序?您是否将因子变量用作分析变量或分组变量?即使您修复了语法错误,您的计划也无法运行。您不能将FACTOR1和FACTOR2都重命名为同一个名称。我认为您可以使用一步过程排序,而不是两步数据+过程排序:过程排序数据=have1keep=time FACTOR1 out=have3\u 1;按系数1计算;跑代替数据2;设置have1;保持时间系数1;跑proc sort data=have2 out=have2_1;按系数1计算;跑为什么宏引用一个完全未定义的宏变量,col\u period?为什么按因子变量而不是按时间排序?您是否将因子变量用作分析变量或分组变量?错误22-322:语法错误,应为以下之一:!、!!、&、*、***、+、'、'、-、/、=、?,和,AS,CONTAINS,EQ,EQT,FROM,GE,GET,GT,GTT,LE,LET,LIKE,LT,LTT,NE,NET,OR,^=,|,| |,~=。这就是我得到的错误。procsql的问题是我是这样应用的。只有第一个因子,因子1,所以我有t2。因子1,因子2,这是错误的,我应该有:t2。因子1,t2。factor2@a.rimbaud正如Tom所示,Proc MEANS有一个大的功能集供您使用。与只将args替换为语句的宏编码不同,学习Procs语句和不使用宏编码意味着支持长期的代码更少,并且使编码器或代码继承器的工作更轻松。错误22-322:语法错误,应为以下之一:!、!!、&、*、**、+、'、'、-、/、=、?,和,AS,CONTAINS,EQ,EQT,FROM,GE,GET,GT,GTT,LE,LET,LIKE,LT,LTT,NE,NET,OR,^=,|,| |,~=。这就是我得到的错误。procsql的问题是我是这样应用的。只有第一个因子,因子1,所以我有t2。因子1,因子2,这是错误的,我应该有:t2。因子1,t2。factor2@a.rimbaud正如Tom所示,Proc MEANS有一个大的功能集供您使用。不是简单地将args替换为语句来编码宏,而是学习Procs语句,不使用宏来编码,这意味着支持长期性的代码更少,并且使编码者或代码继承者的生活更轻松。T
汉克斯·阿列克西让列表=系数1系数2;我是这样写的:%macro testlist;%i=1%到%sysfunccountw&列表,%str;%let factorname=%scan&list,&i,%str;%宏v1数据集、表、时间和列表;%结束%修复试验;但没有返回任何输出。我在宏_v1中也使用了list,对吗?试试这个:%macro testlist;%i=1%到%sysfunccountw&列表,%str;%let factorname=%scan&list,&i,%str;%宏v1dataset、表、时间和factorname;%结束;%修补试验;%测试列表;它给了我以下错误:错误:文本表达式&list包含对宏变量list的递归引用。宏变量将被分配空值。@a.rimbaud tfactor从factor_列表中存储一个因子,并在每次迭代中更改。例如,我们有factor_list等于factor1 factor2 factor3,countw函数计算按空格分割的单词数,然后按每个单词循环迭代,tfactor在每次迭代中包含单词在第一次迭代中tfactor包含factor_list的第一个单词,它等于factor1,等等。谢谢Alexey谢谢Alexey让列表=系数1系数2;我是这样写的:%macro testlist;%i=1%到%sysfunccountw&列表,%str;%let factorname=%scan&list,&i,%str;%宏v1数据集、表、时间和列表;%结束%修复试验;但没有返回任何输出。我在宏_v1中也使用了list,对吗?试试这个:%macro testlist;%i=1%到%sysfunccountw&列表,%str;%let factorname=%scan&list,&i,%str;%宏v1dataset、表、时间和factorname;%结束;%修补试验;%测试列表;它给了我以下错误:错误:文本表达式&list包含对宏变量list的递归引用。宏变量将被分配空值。@a.rimbaud tfactor从factor_列表中存储一个因子,并在每次迭代中更改。例如,我们有factor_list等于factor1 factor2 factor3,countw函数计算按空格分割的单词数,然后按每个单词循环迭代,tfactor在每次迭代中包含单词在第一次迭代中tfactor包含factor1的factor_list的第一个单词,等等。谢谢Alexey