0

I have a chunk to bootstrap a dataset.

%let iter = 2;
%let seed = 777;

data work.seg;
    input segment $3. prem loss;
    datalines;
AAA 5000 0
AAA 3000 12584
AAA 200 245
AAA 500 678
;

data work.test;
    do i=1 to &iter;
        sumprem=0;

        do _n_=1 to 1000000 until (sumprem>=8700);
            row_i=int(ranuni(&seed)*n)+1;
            set work.seg point=row_i nobs=n;
            sumprem + prem;
            output;
        end;
    end;

    stop;
run;

It works, but I have a few questions.

  1. How can I make the 400 number dynamic... I want (sumprem >= 8700) to be (sumprem >= &threshold) where &threshold is the sum of the prem column.
  2. Is it correct how I am passing the &seed? Or should (&seed) be replaced with something like (&seed + _n_)?
  3. How can I make the last data step into a macro... something like below, but I haven't gotten anything to work.

    %macro boot(data, iter, seed);
    
        %do i=1 %to &iter;
    
        sumprem=0;
    
        %do _n_=1 %to 1000000 %until (sumprem>=8700);
            row_i=int(ranuni(&seed)*n)+1;
            set work.seg point=row_i nobs=n;
            sumprem + prem;
            output;
        %end;
    %end;
    
    %mend;
    
StupidWolf
  • 45,075
  • 17
  • 40
  • 72
waealu
  • 331
  • 1
  • 9
  • There's no 400 in your code. Instead of passing the seed that way I think I prefer using CALL STREAMINIT(). Is there a reason you're using a data step to sum instead of a PROC. I know DoW loops can be efficient, but I didn't think they were faster than the PROCS. – Reeza Dec 07 '18 at 20:26
  • http://www2.sas.com/proceedings/forum2007/183-2007.pdf – Reeza Dec 07 '18 at 21:40

1 Answers1

0

I assume you want to calculate the sum of prem from work.seq?

proc sql noprint ;
  select sum(prem) format=best32. into :threshold trimmed from seg ;
quit;

Your macro code is confusing macro logic, which can be used to generate code, and data step logic which is what operates on the actual data. To make it into a macro just use the same macro variable names for the names of the parameters to the macro and leave the code the same.

%macro boot(in,out, iter, seed);
data &out;
  do until (eof);
    set &in end=eof;
    threshold + prem ;
  end;
  do i=1 to &iter;
    sumprem=0;
    do _n_=1 to 1000000 until (sumprem>=threshold);
      row_i=int(ranuni(&seed)*n)+1;
      set &in point=row_i nobs=n;
      sumprem + prem;
      output;
    end;
  end;
  stop;
run;
%mend boot;
Tom
  • 47,574
  • 2
  • 16
  • 29