The SAS Output Delivery System and reporting techniques

Numeric value split

Reply
Frequent Contributor
Posts: 115

Numeric value split

Hi,

I have a to include below validations for one of my requirement

If the current quantity value is less 0,083 the new quantity value should be 0.

If the current quantity value is greater then or equal to 0,083 the new quantity value should be 1 (rules applies till quantity 10)

If the current quantity value is greater then or equal to 10 the new quantity vaults should be normal rounding.

ex: if quantity value is 2.056 then quantity value should be 2. if if quantity value is 11.056 then quantity value should be 11.1

I need to include below validations from 0 to 10

ex: if nums lt < 0.083 then nums=0;

else if nums ge 0.083 and nums le 1 then nums =1;

else if nums ge 1 and nums lt < 1.083 and  then nums=1;

else if nums ge 1.083 and nums le 2 then nums =2;

-------

------

----

else if nums nums ge 9 and nums lt < 9.083 then nums=9;

else if nums ge 9.083 and nums le 10 then nums =10;

else nums=round(nums,0.1);

instead of using repeted validations from 0 to 10, any way to use single validation for all above.

Could you please let me know the best way to do it for all my all numeric variables to fulfil my requirement

Super User
Posts: 19,805

Numeric value split

Posted in reply to sunilreddy

I'm not sure exactly what you're asking for, I read it as a combination of rounding requirements and recoding, but not sure which goes where. Some more sample data might help. 

Assuming rounding, 3 if statements with the round function will give you what you want but I don't think the rules are very clear.

data have;

    input num;

    cards;

0.05

0.0830

0.9

1

5.4556

2.456

9.3

9.9

10.0343

11.34343

23.343

;

run;

data want;

set have;

if num<0.083 then new_number=0;

else if num<10 then new_number=round(num, 1);

else new_number=round(num, 0.1);

run;

PROC Star
Posts: 7,474

Numeric value split

Posted in reply to sunilreddy

Presuming the 10 in your requirements was supposed to be a 1, I think the following does what you want:

data have;

    input num1-num3;

    cards;

0.05 1.3 2.6

0.0830 4 5.2

0.9 5.6  7.1

1 2 3

5.4556 5.1 5.6

2.456 6 7

9.3 3 .2

9.9 4 .4

10.0343 .6 .7

11.34343 3 8

23.343 12.2 12.5

;

data want;

  set have;

  array nums _numeric_;

  do over nums;

    if nums lt 0.083 then nums=0;

     else if nums le 1.0 then nums=1;

     else nums=round(nums, 1);

  end;

run;

Frequent Contributor
Posts: 115

Numeric value split

Thanks a lot for your help.

I need to include below validations from 0 to 10

ex: if nums lt < 0.083 then nums=0;

else if nums ge 0.083 and nums le 1 then nums =1;

else if nums ge 1 and nums lt < 1.083 and  then nums=1;

else if nums ge 1.083 and nums le 2 then nums =2;

-------

------

----

else if nums nums ge 9 and nums lt < 9.083 then nums=9;

else if nums ge 9.083 and nums le 10 then nums =10;

else nums=round(nums,0.1);

instead of using repeted validations from 0 to 10, any way to use single validation for all above.

Occasional Contributor
Posts: 18

Re: Numeric value split

Posted in reply to sunilreddy

A Suggestion with proc report:

data test;
  input number expectednumber; 
  cards;
0.071 0
0.71 1
0.91 1
1.51 2
1.91 2
2.41 2.4
2.81 2.8
9.05 9
9.41 10
11.81 11.8
run;

proc format; value number
low - < 0.083  = 0.0
0.083 - 1.083  = 1.0
1.083 -  2     = 2.0
9 -  < 9.083   = 9.0
9.083 - 10     = 10.0
;run;

data new; set test;
numbernew = round(put(number,number.),0.1);
run;

PROC Star
Posts: 7,474

Re: Numeric value split

Posted in reply to sunilreddy

Is there a chance you made a mistake in your third requirement.  Both the 2nd and 3rd are shown to result in 1.  Should they be 1 and 2?

If so, you might be able to use something like:

data have;

    input num1-num3;

    cards;

0.083 1.082 2.083

0.083 4 5.2

0.9 5.6  7.1

1 2 3

5.4556 5.1 5.6

2.456 6 7

9.082 9.083 9.084

9.9 4 .4

10.0343 .6 .7

11.34343 3 8

23.343 12.2 12.5

;

data want;

  set have;

  array nums _numeric_;

  do over nums;

    if nums ge 10 then nums=round(nums, 1);

    else do;

      nums=nums-.083;

      nums=ceil(nums);

    end;

  end;

run;

Frequent Contributor
Posts: 115

Re: Numeric value split

Posted in reply to sunilreddy

Getting below error if am using format for nums = round(put(nums,number.),0.1);

ERROR: Array subscript out of range at line 43 column 5.

number=0.071 expectednumber=0 _I_=. _ERROR_=1 _N_=1

data test;
  input number expectednumber; 
  cards;
0.071 0
0.71 1
0.91 1
1.51 2
1.91 2
2.41 2.4
2.81 2.8
9.05 9
9.41 10
11.81 11.8
run;


proc format; value number
low - < 0.083  = 0.0
0.083 - 1      = 1.0
1    - < 1.083    = 1.0
1.083 - 2      = 2.0
9 -  < 9.083   = 9.0
9.083 - 10     = 10.0
;run;


data new1; set test;
array nums _numeric_;
if nums <= 10.0 then
     nums = round(put(nums,number.),0.1);
else nums=round(nums,0.1);
run;

i need to use array construct for all numeric variables in dataset.

Occasional Contributor
Posts: 18

Numeric value split

Posted in reply to sunilreddy

If you insist on the <=10 condition, you could do it as follows:

data new1; set test;

if number <= 10.0 then nums = round(put(number,number.),0.1);

else nums=round(number,0.1);

run;

But it is not neccesary. Why do you use this array-construct?

Frequent Contributor
Posts: 115

Numeric value split

Thanks for you reasponse.

I want to use this validation for all numeric variables in dataset for my requirement.

Super User
Posts: 11,343

Re: Numeric value split

Posted in reply to sunilreddy


I think you want an INVALUE informat not a VALUE format and use INPUTN.

Frequent Contributor
Frequent Contributor
Posts: 83

Numeric value split

Posted in reply to sunilreddy


Hi

How about this?

data data_out;

set data_in;

integer_part=int(nums);

U_limit=integer_part+0.083;

if nums le 10 then do;

if nums lt U_limit then nums=inger_part;

end;

else if nums gt 10 then do;

nums=round(nums.0.1);

drop integer_part U_limit;

run;

Frequent Contributor
Frequent Contributor
Posts: 83

Numeric value split

Posted in reply to sunilreddy

sorry Sunil . I missed one line while typing

The code should be;

data data_out;

set data_in;

integer_part=int(nums);

U_limit=intger_part+1;

if nums le 10 then do;

if nums lt U_limit then nums=integer_part;

else if nums ge U_limit then nums=integer_part+1;

end;

else if nums gt 10 then do;

nums=round(nums,0.1);

end;

drop integer_part U_limit;

run;

Ask a Question
Discussion stats
  • 11 replies
  • 1158 views
  • 3 likes
  • 6 in conversation