BookmarkSubscribeRSS Feed
den
Calcite | Level 5 den
Calcite | Level 5
Dear all,

I was wondering if anybody knows the answer to the following? I have a macro listing various different statistical distributions. If I wish to simulate values from a certain distribution, I change the name of the macro variable which refers to that distribution.

eg %let distribution='Normal'
......
if &distribution="Normal" then distribution=rand('Normal',0,1);

I would like to be able to call output generated by the distribution by the corresponding distribution name. For the above example the output dataset name would be "Normal". I have tried writing a new macro variable eg %let outdata=&distribution but this doesn't appear to work. Any thoughts on how to resolve this would be much appreciated.
11 REPLIES 11
CurtisMack
Fluorite | Level 6
I am not completely understanding your question, but one thing that may be causing you grief is the single quotes in you macro variable assignment. These are not needed, and in fact will apear when the value is resolved.
den
Calcite | Level 5 den
Calcite | Level 5
I've also tried taking the quotes out of the macro variable but this doesn't work either.
CurtisMack
Fluorite | Level 6
Is this what you are looking for?

%let distribution=Normal;

data junk;
distribution=rand("&distribution",0,1);
run;
CurtisMack
Fluorite | Level 6
This will also work and is closer to your original code, but it not optimal IMHO.

%let distribution=Normal;

data junk;
if "&distribution" = "Normal" then distribution=rand("NORMAL",0,1);
else if "&distribution" = "POISSON" then distribution=rand("POISSON",0,1);
run;
den
Calcite | Level 5 den
Calcite | Level 5
Maybe I didn't explain the issue I'm having very well. I would like to be able to name the dataset containing the simulated values after the distribution for which I'm simulating the values for. So if I'm simulating the values of a normal distribution, I would like the output dataset to be called 'Normal.sas7bdat'


Eg. &outdata=name of distribution;
&distribution=Normal;
......

data &outdata;
if &distribution='Normal' then do; response=rand('NORMAL',0,1);
end;
output;
run;

I would like to be able to name the dataset for each distribution in turn without having to change the value of the &outdata macro variable each time. I would like it to be able to refer to the &distribution macro variable rather than having to change both macro variables for each distribution in turn. If that makes sense? Message was edited by: den
deleted_user
Not applicable
hello,

if you look at ballardw answer, it may be just what you are looking for.

I build a macro, where distribution for which rand function has the same formula are passed to a macro variable.
anyway, depending on distributions you want to store, it should be improved.

[pre]
%macro test;

%let x=table,Normal;

%let a=%sysfunc(countw(%NRQUOTE (&x),%NRQUOTE (,)));

%do i=1 %to %eval(&a);

data %scan(%NRQUOTE (&x),%eval(&i),%NRQUOTE (,));
x=%sysfunc(rand (%scan(%NRQUOTE (&x),%eval(&i),%NRQUOTE (,)),0,1));
run;

%end;

%mend test;

%test

[/pre]


Marius

ballardw
Super User
> I would like to be able to name the dataset for each
> distribution in turn without having to change the
> value of the &outdata macro variable each time. I
> would like it to be able to refer to the
> &distribution macro variable rather than having to
> change both macro variables for each distribution in
> turn. If that makes sense?
>
> Message was edited by: den

Time to give a better example of what you are looking to do. It sounds like you are attempting to build multiple datasets with one pass but you only have one assignment to DISTRIBUTION at a time, so only one output set would be created.

Did you run my example code and did it create a data set named with the distribution or not? Or are you wanting the parameters involved in the data set name as well? That may require things not available in open code.
den
Calcite | Level 5 den
Calcite | Level 5
Yes, I'm looking to create one dataset at a time. I would like to save the output of this dataset by the name of the distribution which has been simulated eg normal.sas7bdat, binomial.sas7bdat. The intention is to create lots of different datasets with a different distribution in each and then to combine these datasets together at a later stage.
Reeza
Super User
Could you use one macro variable for the name of the data set and the distribution?

The following is an example (if it shows up) of using one name to generate the sample.


%macro generate_random_sample(distribution, sample_size);

data &distribution;
if upcase("&distribution.")='NORMAL' then do; do i=1 to &sample_size; response=rand('Normal',0,1); output; end; end;
else if upcase("&distribution.")='BINOMIAL' then do; do i=1 to &sample_size; response =rand('Binomial', 0.5, 1000); output; end; end;

run;

%mend;

%generate_random_sample(Normal, 50);
%generate_random_sample(Binomial, 50);
FloydNevseta
Pyrite | Level 9
You can genralize the macro even more by passing the parameters of the RAND function into the macro. Such as:

%macro create_random_sample ( sample_size, distribution_parameters );
* strip the quotes from the distribution name;
%let distribution = %sysfunc( compress( %scan( &distribution_parameters, 1, %str(,) ), %str(%') ));

data &distribution;
do until ( id = &sample_size );
id + 1;
dist_var = rand( &distribution_parameters );
output;
end;
run;
%mend;

%create_random_sample ( 100, %str('normal', 0, 1) );
%create_random_sample ( 100, %str('t', 4) );
%create_random_sample ( 100, 'logn' );
%create_random_sample ( 100, %str('poisson', 6.1) );
%create_random_sample ( 100, %str('binom', .75, 10) );
ballardw
Super User
> Dear all,
>
> I was wondering if anybody knows the answer to the
> following? I have a macro listing various different
> statistical distributions. If I wish to simulate
> values from a certain distribution, I change the name
> of the macro variable which refers to that
> distribution.
>
> eg %let distribution='Normal'
> ......
> if &distribution="Normal" then
> distribution=rand('Normal',0,1);
>
> I would like to be able to call output generated by
> the distribution by the corresponding distribution
> name. For the above example the output dataset name
> would be "Normal". I have tried writing a new macro
> variable eg %let outdata=&distribution but this
> doesn't appear to work. Any thoughts on how to
> resolve this would be much appreciated.

I think you main issue is defining the macro variable with the quotes.

Try: %let distribution=NORMAL;

data &distribution;
if upcase("&distribution")='NORMAL' then x=rand ('NORMAL',0,1);
run;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 1400 views
  • 0 likes
  • 6 in conversation