SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Hello_there
Lapis Lazuli | Level 10

Hi, I'm trying to produce a random list of numbers that have random decimal lengths and run it through 3 categorical groups. Ideally the number of decimals shouldn't exceed 3, and also some integers. Having at least 100 values or more for each group would be the goal.

 

Something like this would be great:

Group val

Grp1 123.45

Grp2 134

Grp3 443.134

Grp1 122

Grp2 1245.45

Grp3 49302.1

Grp1 233.12

Grp2 343.23

Grp3 333.1

....

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Quentin
Super User

@Hello_there wrote:
How would i be able to vary the round function between 0 to 3 decimal places?

You can use another call to RAND to generate the integers 0-3, and then use that as an input to the ROUND function, e.g.:

 

data have(keep=group val places val2);
  a=-5; b=5;
  do i=1 to 100;
    do group="grp1", "grp2", "grp3";
      u=rand("Uniform");
      val=a+(b-a)*u;
      places = rand("Integer", 0, 3);
      val2=round(val,10**(places*-1)) ;
      output;
    end;
  end;
run;

proc print data=have ;
run ;

Note that as mentioned when you PRINT the rounded data you won't see values varying number of places, because SAS is still storing them all as numbers.  If you want to actually see values with varying number of places, you might want to consider converting this variable to character.  But it all depends on what your macro is designed to do.

The Boston Area SAS Users Group is hosting free webinars!
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.

View solution in original post

16 REPLIES 16
PaigeMiller
Diamond | Level 26

Yes, generate random numbers and then round them as needed to the desired number of decimal places, using the ROUND() function.

 

It would be a good idea for you to state why you need this, and what will be done with these numbers once you have generated them.

--
Paige Miller
Hello_there
Lapis Lazuli | Level 10
The goal is to have random decimal lengths within each group.

Is there a random round function or something like that?
PaigeMiller
Diamond | Level 26

@Hello_there wrote:
The goal is to have random decimal lengths within each group.

This is not a sufficient explanation, what are you going to do with these rounded numbers once you generate them?

--
Paige Miller
Hello_there
Lapis Lazuli | Level 10
I'm creating a macro that will take the maximum value the amount of decimals per group and use that for a formatting situation for presenting descriptive summaries.
PaigeMiller
Diamond | Level 26

It's not good enough in this output to have all values rounded to, for example, 3 decimal places? Why not?

--
Paige Miller
Hello_there
Lapis Lazuli | Level 10
Because for my situation, the data always varies decimal place lengths within groups and between groups.

I didn't think it was probably possible, so it's probably better to just make up the data manually.
Quentin
Super User

There is not a "random round" function, but as Paige mentioned, you can do it in two steps.  First  generate the random number which will have a lot of decimal places.  Then use the round function to round it as you like.  You could even use another random number to decide whether the number should be rounded to 1, 2, or 3, decimal places.  Are you familiar with random number generation in SAS?  To start with, you could try writing the code to generate a dataset with three groups (Group="Grp1" "Grp2" "Grp3"), 100 records per group, with a random value for each record.  Is that something you're comfortable coding?

The Boston Area SAS Users Group is hosting free webinars!
Next up: SAS Trivia Quiz hosted by SAS on Wednesday May 21.
Register now at https://www.basug.org/events.
Hello_there
Lapis Lazuli | Level 10

This is what i have so far.

 

data have (keep=group val);
a=-5; b=5;
	do i=1 to 100;
		do group="grp1", "grp2", "grp3";
		u=rand("Uniform");
		val=a+(b-a)*u;
	output;
		end;
	end;
run;
Hello_there
Lapis Lazuli | Level 10
How would i be able to vary the round function between 0 to 3 decimal places?
ballardw
Super User

@Hello_there wrote:
How would i be able to vary the round function between 0 to 3 decimal places?

Generate enough random numbers. The trailing 0 that occur randomly would effectively be the same as no digits.

1.1 would be the same as 1.100 or 1.1000000 for any "grouping" or "formatting" purpose so I don't see where your number of digits is actually a serious constraint on anything.

 

Show an entire worked problem starting with some manually created values and then show the number of decimal digits is actually used.

Hello_there
Lapis Lazuli | Level 10
Thanks for the info and putting that into a context i hadn't considered.
Hello_there
Lapis Lazuli | Level 10

@ballardw wrote:

@Hello_there wrote:
How would i be able to vary the round function between 0 to 3 decimal places?

 

Show an entire worked problem starting with some manually created values and then show the number of decimal digits is actually used.


Did you mean show you what my use case is for having varying decimal digits? This is for summarizing data by taking the average, the standard deviation, other descriptive stats. Typically there are presentation conventions for how they should be displayed, and usually it's something in line with the "The mean should be one more than the maximum number of digits in the raw data." So if the maximum amount of digits extends to 2 decimal places, i'm supposed to present the mean to 3 decimal places.

ballardw
Super User

@Hello_there wrote:

@ballardw wrote:

@Hello_there wrote:
How would i be able to vary the round function between 0 to 3 decimal places?

 

Show an entire worked problem starting with some manually created values and then show the number of decimal digits is actually used.


Did you mean show you what my use case is for having varying decimal digits? This is for summarizing data by taking the average, the standard deviation, other descriptive stats. Typically there are presentation conventions for how they should be displayed, and usually it's something in line with the "The mean should be one more than the maximum number of digits in the raw data." So if the maximum amount of digits extends to 2 decimal places, i'm supposed to present the mean to 3 decimal places.


You may be running into some things about computer precision of storing decimal values in binary and the fact that some just don't do well.

Also you will have a fun bit getting the significant number of digits in decimals in general because of the way numbers are stored.

 

Example: ALL of these appear exactly the same for a given format. So how do you "know" that a value in your data set of 1 should be considered as 1.00, and especially when using a rule about "one more decimal place"? You determine which formats are to be used before you read the data by the characteristics of the file sent. Not by examining values in the data after it is read.

data example;
   input x;
   put "Best format" x= best6. ;
   put "3.1 format" x= 3.1;
   put "4.2 format" x= 4.2;
   put "5.3 format" x= 5.3;
 datalines;
1
1.0
1.00
1.000
1.0000
;
Hello_there
Lapis Lazuli | Level 10
This is a view I had not considered. I have to think about it some more.

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 16 replies
  • 2908 views
  • 4 likes
  • 4 in conversation