Bootstrap SAS 中的宏

Bootstrap macro in SAS

我开始在 SAS 中学习 %macro,现在我正在尝试使用直方图作为输出来实现简单的 bootstrap。

/*Create K data sets(vectors)*/
%macro datasets(K);
    %do i=1 %to &K;
        data indata&i;
            %do j = 1 %to 50;
             x=(rand('normal',2,9));
            output;
            %end;
        run;
    %end;   
%mend datasets;

%datasets(3);

/*Bootstrap and hist*/
%macro boot (data,res);
    %do i=1 %to &res;
        %let x = (sample(&data,50));
        %let m = (mean(&x));
    %end;
    proc iml;
        read &m into A;
        create DataM from A;
        append from A;
        close Data1;
    quit;
    proc univariate data=Data1;
    histogram m;
    run;
    %mend boot;
%boot(Indata1,100);

它不起作用,我不明白为什么。你能指出我的错误吗?

使用 PROC SURVEYSELECT 生成 bootstrap 个样本,然后通过 Replication(SURVEYSELECT 创建的变量)进行 bootstrap 分析。你的宏观思路太慢了。

如前所述,使用 Proc SurveySelect 和 Proc Means。您可以 select 一个 Proc SurveySelect 中的所有 100 个样本,然后应用带有 BY 语句的 Proc Means 一步计算均值。宏不会在此处向解决方案添加任何内容。

我正在发布这两种解决方案 - 宏解决方案也需要更长的时间。

*Without macro;
proc surveyselect data=indata1 out=rsample method=srs n=50 reps=100;
run;

proc means data=rsample noprint;
by replicate;
var x;
output out=Data1 mean(x)=m;
run;

proc univariate data=Data1;
histogram m;
run;

*Macro solution;

%macro boot(data, res);
%do i=1 %to &res;

%*Currently pulls the same sample every time but you can fix that part;
proc surveyselect data=&data out=x method=srs n=50 reps=1 seed=343434;
run; 

proc means data=x noprint;  
var x;
output out=m mean(x)=m;
run;

proc append base=DataM data=m;
run;

%end;

%mend;

%boot(Indata1,10);

如果我们概述一些发布的宏代码不起作用的方式,也许会有所帮助。如果不出意外,那么作为要避免的事情的例子。

如果第一个宏 %datasets(),您使用的是宏 %DO 循环,您应该使用普通数据步骤 DO 循环。还要确保将本地宏变量定义为本地。这将防止宏修改同名的现有宏变量的值。

/*Create K data sets(vectors)*/
%macro datasets(K);
  %local i ;
  %do i=1 %to &K;
    data indata&i;
       do j = 1 to 50;
         x=(rand('normal',2,9));
         output;
       end;
       drop j;
    run;
  %end;   
%mend datasets;

在第二个宏中,您有一个 %DO 循环,它什么都不做。

%do i=1 %to &res;
  %let x = (sample(&data,50));
  %let m = (mean(&x));
%end;

您多次重复完全相同的 %LET 语句。结果没有改变,因为循环变量 i 根本没有被引用。如果您使用 data=indata1 调用宏,那么这两个语句的结果将是 X=(sample(indata1,50)) 和 M=(mean((sample(indata1,50))))。我认为也许您希望字符串 samplemean 可能会采取一些行动,但由于它们没有宏触发器(&%),它们只是流字符到宏处理器。

我不是IML方面的专家,但这些说法看起来也没什么作用。