- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Esteemed Advisers,
I know I'll be embarassed when the answer comes back on this question:
The goal of the attached code is to generate 10 random meteors within each of two volumes of sky. Each meteor must be at least 10 units in length.
The code produces 10 satisfactory meteors for Target A but none for Target B.
What is the correct way to formulate this DO LOOP to process both TARGET A and B in dataset TargetArea?
Thanks in advance,
Gene
Data TargetArea;
Input Target $ txmin txmax tymin tymax tzmin tzmax;
datalines;
A 0 5 0 5 70 120
B 0 10 0 10 70 120
run;
/* SAS macro from Wicklin for generating Random Numbers between a Min and Max */
%macro RandBetween(min, max);
(&min + floor((1+&max-&min)*rand("uniform")))
%mend;
data Random_Meteors (keep= target meteorct1 meteorct2);
set work.targetarea;
meteorct1=0;
do while (meteorct2<10);
TX_Start = %RandBetween(txmin, txmax);
TY_Start = %RandBetween(tymin, tymax);
TZ_Start = %RandBetween(tzmin, tzmax);
TX_End = %RandBetween(txmin, txmax);
TY_End = %RandBetween(tymin, tymax);
TZ_End = %RandBetween(tzmin, tzmax);
meteorct1+1;
TrackLength=sqrt((TX_Start-TX_End)**2+(TY_Start-TY_End)**2+(TZ_Start-TZ_End)**2);
/* if tracklength<10, generate another meteor until it finds one with tracklength >=10*/
if tracklength<10 then continue;
else;
meteorct2+1;
output;
end;
run;
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You have an error in your IF statement. There is a semi-colon after the "else". That means that Meteor2 is incremented unconditionally (every time) rather than checking for meteors of the proper size. Delete the semi colon and re-run.
if tracklength<10 then continue;
else;
meteorct2+1;
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You are using the summing statement
meteorct2+1;
which will retain the value of 10 achieved in the first observation as the starting value for the 2nd obs. As a result the "do while (meteorct2<10);" loop will never be activated in the 2nd obs.
Use
meteorct2=sum(meteorct2,1);
instead. It will not retain values across observations.
The hash OUTPUT method will overwrite a SAS data set, but not append. That can be costly. Consider voting for Add a HASH object method which would append a hash object to an existing SAS data set
Would enabling PROC SORT to simultaneously output multiple datasets be useful? Then vote for
Allow PROC SORT to output multiple datasets
--------------------------
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
You've received good findings from @jimbarbour and @mkeintz. I'll just add that the DATA step debugger (available in SAS Enterprise Guide and SAS Studio) can be used to find logic/behavior errors like this!
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Thanks @ChrisHemedinger
The interactive debugger is a truly beautiful feature of Enterprise Guide. I really don't consider Enterprise Guide to have become excellent until version 7.1.3 (as I recall) came out which included the debugger. Versions 5.1 up to 7.1.2 were good but not excellent. Versions prior to 5.1, uh, well, they weren't so good. 🙂
Jim
- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content
Gene