Precision Floors and Ceilings!
Rounding numeric values is a common task in SAS code and easily achieved using the ROUND function, which enables rounding to any unit. The value will be rounded up or down depending on its proximity to the nearest multiple of the desired unit.
It can also be useful to specifically round values up or down, for example to preserve a minimum sample size for a survey or clinical trial. The CEIL and FLOOR functions provide a means to specifically round up or down respectively, but they are limited to the nearest integer. For example it is not possible to specifically round up to the nearest multiple of 10. Fortunately there is a simple solution to this problem using just a little logic. The following worked example shows how we can round up 1134 to the nearest multiple of 500 [note that ROUND(1134,500) = 1000]:
- Work out how many times 500 goes into 1134, i.e. 1134 / 500 = 2.268
- Round this value up to the nearest integer, i.e. CEIL(2.268) = 3
- Multiple this value by the rounding unit, i.e. 3 * 500 = 1500
This logic works for rounding up any value to any unit, just swap the desired unit into steps 1 and 3. The following SAS data step shows how this can be applied, rounding up and down to the nearest multiple of 100 this time:
data one; do size = 0 to 100 by 25; sizeUp100 = 100 * ceil(size/100); sizeDown100 = 100 * floor(size/100); output; end; run;
Which yields the following output:
However, wouldn't it be nice if this was all wrapped up in a standard SAS data step function? Without going into the code, in detail Proc FCMP can be used to define two custom functions that we can use in our data steps to do just this.