Does anyone has more experience with Proc Surveyselect and Macro?

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 8
Accepted Solution

Does anyone has more experience with Proc Surveyselect and Macro?

I want to randomly sample each one of my ten fields until it achieve the precision of 0.10. I mean, I want to sample with replacement each field and save the mean and variance of insects. Precision is calculated dividing the standard error of mean by mean (SEM/m). For instance, when my sample size is 20, my precision is 0.40. Increasing sample size will increase precision (i.e., 300 samples will give me the desired precision of 0.10).


I attached my data set. I believe the problem is in the loop.


/*DATA Tibraca;

INPUT Field    Adult ;*/

%LET J=100.10;

%LET K=100.20001; /*Starting the process with a valid statement, K>100.20*/

%LET I=1; /*This is my initial sample size*/

%MACRO Sampling;

%DO %UNTIL (K>100.20); /*When I have precision=0.10, K will not be greater than 100.20, 100.10 (J) + 0.10 (Prec) = 100.20. It will kill the process*/

/*If I have a small sample size (i), Prec will be greter than 0.10. Then, process will keep going because K is not less than 100.20*/

PROC SORT DATA=TIBRACA; BY Field; RUN;

PROC SURVEYSELECT DATA=TIBRACA NOPRINT

OUT = SimpleSample

METHOD = SRS

SAMPSIZE = &I; /*Sample size*/

STRATA Field; /*I have 10 fields that should be considered separately*/

RUN;

DATA MERGING;

SET SimpleSample;

RUN;

PROC MEANS DATA=MERGING MEAN STDERR N NOPRINT; /*Calculating mean and SEM, later Precision=SEM/m*/

BY Field;

VAR Adult;

OUTPUT OUT=STATS; RUN;

DATA STATS2;

SET STATS;

IF _STAT_ ="MEAN" THEN AVG=Adult; /*Dummy variables*/

IF _STAT_ ="STD" THEN SEM=Adult;

RUN;

/*Putting Mean and SEM in the same raw because I need to calculate SEM/mean*/

PROC MEANS DATA=STATS2 NOPRINT; CLASS Field; VAR AVG; OUTPUT OUT=STATS3; RUN;

PROC MEANS DATA=STATS2 NOPRINT; CLASS Field; VAR SEM; OUTPUT OUT=STATS4; RUN;

DATA STATS5;

MERGE STATS3 STATS4;

IF _STAT_ ^="MEAN" THEN DELETE;

IF Field ="." THEN DELETE;

PREC=SEM/AVG; /*Calculating precision for each run with &I sample size*/

RUN;

%put I=&I+1; /*Is here the problem?*/

%put K=&J+PREC; /*Testing if I the sample size is already enough to have PREC=0.10.*/

%END;

%MEND Sampling;

%Sampling

RUN;

PROC PRINT DATA=STATS5; RUN; Title "Stopped with &I samples"; RUN;


Accepted Solutions
Solution
‎12-17-2013 10:38 PM
Occasional Contributor
Posts: 8

Re: Does anyone has more experience with Proc Surveyselect and Macro?

Dear peers,

I appreciated so much your help.

After several consecutive hours, I have figured out this code.

My process will sample with replacement the field and stops when achieve a precision of 0.10.

I am pasting this code here. I hope that it saves time of someone else...

It may be dirty yet. It is my first macro code in SAS.

%LET d=100.20001;

%LET i=1;

%LET PREC=0; RUN;

%MACRO Sampling;

%DO %WHILE (&d>100.10 or &d<10);

    PROC SURVEYSELECT DATA=ONLYFIELD NOPRINT

    OUT = SimpleSample

    METHOD = URS OUTHITS /*Simple Random, With replacement*/

    N = &i; /*Sample size*/

    RUN; 

    PROC MEANS DATA=SimpleSample MEAN STD N NOPRINT;

    VAR Adult;

    OUTPUT OUT=STATS MEAN=AVG STD=STDEV N=NUM; RUN;

   

    DATA STATS2;

    SET STATS;

    SNUM=SQRT(NUM);

    PREC=(STDEV/(AVG*SNUM));

    d=(PREC+100);

    call symput('AVG',AVG);

    call symput('d',d);

    call symput('PREC',PREC);

    RUN;

    %LET i=%eval(&i+1);

    Title "Sample size is &i units, prec is &PREC, d is &d, avg is &avg."; RUN;

        PROC PRINT DATA=STATS2; RUN;

%END;

%MEND Sampling;

%Sampling

RUN;

View solution in original post


All Replies
Super User
Posts: 19,851

Re: Does anyone has more experience with Proc Surveyselect and Macro?

You may have more than one mistake, but for starters... This should be &K not K

%DO %UNTIL (K>100.20);

And I believe that

%put I=&I+1; /*Is here the problem?*/

%put K=&J+PREC; /*Testing if I the sample size is already enough to have PREC=0.10.*/

Should be %LET rather than %PUT, as put displays variable and LET creates variables.

You may also want to add the %eval function to those,

%let I=%eval(&I+1); /*Is here the problem?*/

%let K=%eval(&J+PREC); /*Testing if I the sample size is already enough to have PREC=0.10.*/

Super User
Posts: 11,343

Re: Does anyone has more experience with Proc Surveyselect and Macro?

Since the example code shows J and K with decimal components you'll %sysevalf to do floating point addition.

It doesn't look like PREC is a variable in a data set so the &J + PREC is likely not to work as PREC will be treated as a string and fail.

You probably need to create anothe macro variable: %Let Prec= 0.10;

and use &J + &Prec.

However, if you are determining sample sizes you might want to look at proc power to determine sample size since you should have mean and stddev of your varibles as starting point, specify the precision you need.

Occasional Contributor
Posts: 8

Re: Does anyone has more experience with Proc Surveyselect and Macro?

I'm going to make my question easier. I believe that I did not understand how to do the loop in SAS. See this simple code below. It runs the first loop, but doesn't go the the next I+1 loop. Thanks.

Header 1Header 2

%let I=5;

%macro Do_Tests;

    DATA TWO;

    %do %while (&I>0);

    %LET C=%eval(&I+50);

    Ivar=&I;

    Cvar=&C; RUN;

    PROC PRINT DATA=TWO; RUN;

%LET I=%eval(&I-1);

%end;

%mend Do_Tests;

%Do_Tests

Should the result be:

Ivar  Cvar

5     55

4     54

3     53

2     52

1     51

Header 1Header 2

In other hand, if I use %until:

%let I=0;

%macro Do_Tests;

    DATA TWO;

    %do %until (&I<5);

    %LET C=%eval(&I+50);

    Ivar=&I;

    Cvar=&C; RUN;

    PROC PRINT DATA=TWO; RUN;

%LET I=%eval(&I+1);

%end;

%mend Do_Tests;

%Do_Tests

Will the result be:

Ivar  Cvar

0     50

1     51

2     52

3     53

4     54

?

Super User
Posts: 19,851

Re: Does anyone has more experience with Proc Surveyselect and Macro?

Your initial code is different than your sample code in one key respects. If you're looking to loop within a datastep you don't need to use macro logic. If you're looping multiple procedures then you'll need macro logic.

Super User
Super User
Posts: 7,074

Re: Does anyone has more experience with Proc Surveyselect and Macro?

You are confused about when macro code runs relative to when the generated SAS code that it creates run.

Your UNTIL condition seems reversed. If you start I at 0 and increment it by only 1 then it will always be less than 5.

If you want one pass of a datastep to output multiple observations you need to include an OUTPUT statement.

Your problem does not require macro logic.

DATA TWO;

  do ivar = 5 to 1 by -1 ;

    Cvar=ivar+50;

    OUTPUT;

  end;

run;



Solution
‎12-17-2013 10:38 PM
Occasional Contributor
Posts: 8

Re: Does anyone has more experience with Proc Surveyselect and Macro?

Dear peers,

I appreciated so much your help.

After several consecutive hours, I have figured out this code.

My process will sample with replacement the field and stops when achieve a precision of 0.10.

I am pasting this code here. I hope that it saves time of someone else...

It may be dirty yet. It is my first macro code in SAS.

%LET d=100.20001;

%LET i=1;

%LET PREC=0; RUN;

%MACRO Sampling;

%DO %WHILE (&d>100.10 or &d<10);

    PROC SURVEYSELECT DATA=ONLYFIELD NOPRINT

    OUT = SimpleSample

    METHOD = URS OUTHITS /*Simple Random, With replacement*/

    N = &i; /*Sample size*/

    RUN; 

    PROC MEANS DATA=SimpleSample MEAN STD N NOPRINT;

    VAR Adult;

    OUTPUT OUT=STATS MEAN=AVG STD=STDEV N=NUM; RUN;

   

    DATA STATS2;

    SET STATS;

    SNUM=SQRT(NUM);

    PREC=(STDEV/(AVG*SNUM));

    d=(PREC+100);

    call symput('AVG',AVG);

    call symput('d',d);

    call symput('PREC',PREC);

    RUN;

    %LET i=%eval(&i+1);

    Title "Sample size is &i units, prec is &PREC, d is &d, avg is &avg."; RUN;

        PROC PRINT DATA=STATS2; RUN;

%END;

%MEND Sampling;

%Sampling

RUN;

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 6 replies
  • 427 views
  • 9 likes
  • 4 in conversation