BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Anthony_de_Fex
Calcite | Level 5

I was curious to know if there is some sas function that can convert a value of a character variable ("1/3"), to a numeric variable (.333333...). This would save me the trouble of parsing out the different parts of "1/3" into intermediate variables to then use conditional statements to do the calculation. 

It would be nice if input("1/3",8.) would give you .33333

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Not aware of an Informat, which would be the likely took, that would do this.

If the data is "clean" the parse and calculate in pretty simple:

data example;
   input x $;
   if index(x,'/')>0 then number = input(scan(x,1,'/'),12.)/input(scan(x,2,'/'),12.);
datalines;
1/3
10/31
4.5
3.555/17.44
;

The above only does the division when there is a / and a non-fraction value is provided to demonstrate that.

If you have more than one / in the string you're on your own.

View solution in original post

10 REPLIES 10
ballardw
Super User

Not aware of an Informat, which would be the likely took, that would do this.

If the data is "clean" the parse and calculate in pretty simple:

data example;
   input x $;
   if index(x,'/')>0 then number = input(scan(x,1,'/'),12.)/input(scan(x,2,'/'),12.);
datalines;
1/3
10/31
4.5
3.555/17.44
;

The above only does the division when there is a / and a non-fraction value is provided to demonstrate that.

If you have more than one / in the string you're on your own.

Anthony_de_Fex
Calcite | Level 5

thanks, but I was curious to know if there is an easier way than that. Something specifically designed to resolve all manner of arithmetic formulas that could be in a character variable. Some one function like the input function. Also something not involving macros.

Tom
Super User Tom
Super User

No.  

IF the string is just pure arithmetic, like your example, then you could use %sysevalf() macro function.

data have;
  input equation $20.;
cards;
1/3
1+1/2
;

data want;
  set have;
  number=input(resolve(cats('%sysevalf(',equation,')')),32.);
run;

proc print;
run;
Obs    equation     number

 1      1/3        0.33333
 2      1+1/2      1.50000

 If you also have other strings that might be numbers you might also try using the COMMA informat (the "best" informat).

data have;
  input equation $20.;
cards;
1/3
1+1/2
25%
1,234
;

data want;
  set have;
  number=input(equation,??comma32.);
  if missing(number) then 
    number=input(resolve(cats('%sysevalf(',equation,')')),32.)
  ;
run;
Anthony_de_Fex
Calcite | Level 5

Thanks. Something like this is what I was interested in. I don't have anything against macros or macro variables. I want the formulas to be values in a dataset variable, not in a macro variable.

I was just wondering about a unit conversion dataset I was recently looking at. Some of the factors may be truncated decimals from the division of two numbers where the decimals go on to infinity. I was wondering if instead of specifying the truncated result, to just put in the formula and have sas figure out what it resolves to.

ballardw
Super User

@Anthony_de_Fex wrote:

Thanks. Something like this is what I was interested in. I don't have anything against macros or macro variables. I want the formulas to be values in a dataset variable, not in a macro variable.

I was just wondering about a unit conversion dataset I was recently looking at. Some of the factors may be truncated decimals from the division of two numbers where the decimals go on to infinity. I was wondering if instead of specifying the truncated result, to just put in the formula and have sas figure out what it resolves to.


You might look in the documentation of Proc Format that uses a formula stored in a function created by Proc Fcmp to do unit conversions. The example in the documentation shows a Fahrenheit to Celsius and vice versa temperature conversion. These allow putting the division as 1/3 if needed as the Fcmp function would use typical syntax for numeric computation. If the conversion has ranges involved the functions allow testing one or more of the parameters passed to execute the appropriate section of code.

 

https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.4/proc/p1gg77jyhc9s42n1f1vjyx2hsg8b.htm

 

Caveat: If you use these formats you need to make the functions and the formats available to the SAS session. Also do not lose the code to create them. You will likely need to rebuild both the function and the format in later versions of SAS as the format catalog alone may not be sufficient in later software.

PaigeMiller
Diamond | Level 26

@Anthony_de_Fex wrote:

Also something not involving macros.


A pointless limitation. Why do you want to avoid macros?

 

(And technically, no one has proposed a macro solution; what has been proposed is a solution using a macro variable, which is not the same as a macro; or using a macro function %sysevalf, which is not the same as a macro)

--
Paige Miller
PaigeMiller
Diamond | Level 26

If the character string is a syntactically correct statement, put it into a macro variable, and then after that in a DATA step you can do

 

input(&macrovarname,best16.)

--
Paige Miller
Ron_Cody
Obsidian | Level 7

Hi.

 

Try this:

data Test;
informat String $10.;
input String;
Position = findc(String,'/');
if Position then do;
put _all_;
Numerator = substr(String,1,Position-1);
Denominator = substr(String,Position+1);
Number = input (Numerator,10.) / input(Denominator,10.);
end;
else number = input(String,10.);
datalines;
1/3
2/5
8
;
title "Listing of Test";
proc print data=Test;
run;

 

Please check out support.sas.com/Cody to see some of my SAS programming books.

Anthony_de_Fex
Calcite | Level 5

Hi Ron. Thanks for your answer, but that is too much for what I had in mind. I like the input(resolve(cats('%sysevalf(',equation,')')),32.); from the other user.

I've read some of your books by the way, like 20 years ago. 

Ron_Cody
Obsidian | Level 7
Hi.

Glad to hear you have read some of my books. I like simple coding, that
%syseval is too complicated for me! I have two new books using SAS Studio
with OnDemand for Academics. I have become a huge fan of OnDemand and
Studio.

Best,
Ron

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
  • 10 replies
  • 1248 views
  • 5 likes
  • 5 in conversation