DATA Step, Macro, Functions and more

Array processing - Numeric to Character Conversion using a put statement

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 9
Accepted Solution

Array processing - Numeric to Character Conversion using a put statement

Hello!

I am utilizing the following code to convert numeric values to character values.

  array valsc (*) $ vsbpsysc vsbpdiac vspulsec vsrespc;

  array vals (*) vsbpsys vsbpdia vspulse vsresp;

  array norm (*) $ tempnorm bpnorm hrnorm respnorm;

  do i =1 to dim(valsc);

       valsc{i}=strip(put(vals{i},8.));

       if strip(norm{i}) = '' then do;

            valsc{i}=strip(norm{i});

       end;

  end;

I run the code and get no syntax errors, however the values of the array valsc come up as blank values.

When I do each variable individually, ie vsbpsysc=put(vsbpsys ,8.); I get the result I am looking for.


This makes me wonder, is what I am attempting to do possible with arrays (since the elements of the two different arrays are of different types)?




EDIT: I found out what I was doing incorrectly. I had a type-o in my code, it should have read:

if strip(norm{i})^ = '' then do;

            valsc{i}=strip(norm{i});

       end;


Accepted Solutions
Solution
‎07-15-2015 11:18 AM
Super User
Super User
Posts: 7,432

Re: Array processing - Numeric to Character Conversion using a put statement

You have mixed up what has values and what doesn't there. 

data have;

  vsbpsys=12; vsbpdia=13; vspulse=20; vsresp=5;

run;

data want;

  set have;

  array valsc (*) $20. vsbpsysc vsbpdiac vspulsec vsrespc;

  array vals (*) 8. vsbpsys vsbpdia vspulse vsresp;

  do i =1 to dim(valsc);

    valsc{i}=strip(put(vals{i},8.));

  end;

run;

So, I have the numeric values to start with, and they get converted to character.  (also put the full format with length on it as well).

View solution in original post


All Replies
Solution
‎07-15-2015 11:18 AM
Super User
Super User
Posts: 7,432

Re: Array processing - Numeric to Character Conversion using a put statement

You have mixed up what has values and what doesn't there. 

data have;

  vsbpsys=12; vsbpdia=13; vspulse=20; vsresp=5;

run;

data want;

  set have;

  array valsc (*) $20. vsbpsysc vsbpdiac vspulsec vsrespc;

  array vals (*) 8. vsbpsys vsbpdia vspulse vsresp;

  do i =1 to dim(valsc);

    valsc{i}=strip(put(vals{i},8.));

  end;

run;

So, I have the numeric values to start with, and they get converted to character.  (also put the full format with length on it as well).

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

The cats function is the best and easier way to do this conversion these days:

    valsc{i}=cat( vals{i} );

data t;

  array a [2] (-.00000000001234567890123456 -1234567890123456 );

  b1=put(a[1],32.26);  b2=put(a[2],32.);    put b1= @35 b2= ;

  b1=put(a[1],best32.);b2=put(a[2],best32.);put b1= @35 b2= ;

  b1=cat(a[1]);        b2=cat(a[2]);        put b1= @35 b2= ;

run;

b1=-0.00000000001234567890123450  b2=-1234567890123456

b1=-1.2345678901234E-11           b2=-1234567890123456

b1=-1.2345678901234E-11           b2=-1234567890123456

Note that decimal numbers always lose precision for some reason.

I have my sixteen digits for integers (since they are < 9,007,199,254,740,992)

but only 14 ( functions cat() and format best. )  or 15 (format w.d)  for decimals


Message was edited by: Christian Graffeuille

Super User
Super User
Posts: 7,432

Re: Array processing - Numeric to Character Conversion using a put statement

Is it not the purpose of the put and input functions to convert data from numeric to character and vice versa using an Explicitly present format?  Personally I am quite against letting procedures guess what I want the data to look like. 

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

It is but most users never get it right. And cat does just as good a job without having to provide the length or number of decimals: easier and less room for errors.

Respected Advisor
Posts: 3,777

Re: Array processing - Numeric to Character Conversion using a put statement

There is no guessing

If item is numeric, then its value is converted to a character string by using the BESTw. format. In this case, leading blanks are removed and SAS does not write a note to the log.


If you want to convert to character using an associated format look to the VVALUE VVALUEX functions.

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

I never use format best. since it doesn't do as requested/expected.

data t;

*1; X=-0.00000000001234567890123456; Y=put(X,32.30  ); put '1- 32.30     ' Y ;

*2; X=-0.00000000001234567890123456; Y=put(X,best.  ); put '2- best.     ' Y ;

*3; X= 0.00000000001234567890123456; Y=put(X,best.  ); put '2- best.     ' Y ;

*4; X=-0.00000000001234567890123456; Y=put(X,best20.); put '4- best20.   ' Y ;

*5; X= 0.00000000001234567890123456; Y=put(X,best20.); put '5- best20.   ' Y ;

*6; X=-0.00000000001234567890123456; Y=put(X,best32.); put '6- best32.   ' Y ;

*7; X=-0.00000000001234567890123456; Y=put(X,best32.); put '7- best32.30 ' Y ;

*8; X=-1234567890123456000000000000; Y=put(X,32.30  ); put '8- 32.30     ' Y ;

run;

Yields:

1- 32.30    -.000000000012345678901234560000

2- best.     -1.23457E-11

2- best.           1.234568E-11

4- best20.   -1.2345678901235E-11

5- best20.       1.2345678901234E-11

6- best32.   -1.2345678901234E-11

7- best32.30 -1.2345678901234E-11

8- 32.30     -1234567890123456163050684416.00


Line 1: Format 32.30 displays all the wanted digits, as requested by the length of 32.

Line 2-3: Format best. drops many digits as its default length is 12. Let's accept this is a design decision.

Line 4-5: Format best20. does what's on the tin for negative numbers (but rounding is wrong), but does not use the full length for positive numbers.

Line 6-7: Format best32. does not display the requested precision, It behaves as format best20.

Line 8 : Format 32.30 doesn't correctly writes large integers but is still the "best" format here.

Respected Advisor
Posts: 3,777

Re: Array processing - Numeric to Character Conversion using a put statement

I sure I don't understand your point.  In one thread you say that CAT is the "best" way to convert numeric to character and in another you say "I never use BEST format".

As for rounding with W.D format "everyone" knows that it doesn't always round as expected as shown in this example.

data _null_;
  
x = -1e-12;
   y = round(x,
10**-6);
   put x=10.6 x= y=10.6 y=;
   run;

x=-0.000000 x=-1E-12 y=0.000000 y=0
PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

1- I am saying cat() is good enough, precise enough, fast and easy.

    If I need full control then w.d is the best.

    Format best. the worst, cat() matches or bests any best. format.

data t;

*1; X=-0.00000000001234567890123456; Y=put(X,32.30  ); put '1- 32.30     ' Y ;

*2; X=-0.00000000001234567890123456; Y=put(X,best.  ); put '2- best.     ' Y ;

*3; X= 0.00000000001234567890123456; Y=put(X,best.  ); put '2- best.     ' Y ;

*4; X=-0.00000000001234567890123456; Y=put(X,best20.); put '4- best20.   ' Y ;

*5; X= 0.00000000001234567890123456; Y=put(X,best20.); put '5- best20.   ' Y ;

*6; X=-0.00000000001234567890123456; Y=put(X,best32.); put '6- best32.   ' Y ;

*7; X=-0.00000000001234567890123456; Y=put(X,best32.); put '7- best32.30 ' Y ;

*8; X=-1234567890123456000000000000; Y=put(X,32.30  ); put '8- 32.30     ' Y ;

*9; X=-0.00000000001234567890123456; Y=cat(X); put '9- cat()     ' Y ;

*10; X=-1234567890123456000000000000; Y=cat(X); put '10- cat()    ' Y ;

run;

1- 32.30     -.000000000012345678901234560000
2- best.     -1.23457E-11
2- best.     1.234568E-11

4- best20.   -1.2345678901235E-11

5- best20.    1.2345678901234E-11

6- best32.   -1.2345678901234E-11

7- best32.30 -1.2345678901234E-11

8- 32.30    -1234567890123456025611730944.00
9- cat()    -1.2345678901234E-11
10- cat()   -1234567890123456025611730944

2- I don't understand what you are trying to show.

I am just showing that

4- best20.   -1.2345678901235E-11

is wrong. The right value for this string length would be

4- best20.   -1.2345678901234E-11

which is what the other formatted strings contain.

Anyway to each their own...

Respected Advisor
Posts: 3,777

Re: Array processing - Numeric to Character Conversion using a put statement

1) You need read the documentation; CAT uses BEST so there is no difference.  CAT does quietly convert to character with no annoying conversion note.

2) I was saying that rounding cannot always left to w.d as it gets it wrong sometimes as shown by my example where w.d displays negative zero.

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

CAT uses BEST32., not BEST.

Shorter BEST. formats (which everydody uses) can yield surprises as I've shown.

So *my opinion* is : why bother, cat is easier to use and to teach, so that's what I do now.

That's the only point I have been making, and I made this point as I think it has value for less experienced SAS users.

Feel free to disagree. I've said all I had to say on this matter.  Smiley Happy

Super User
Super User
Posts: 7,432

Re: Array processing - Numeric to Character Conversion using a put statement

Hi,

Yes, disagree slightly here.  The use of cat would then be hiding and additional conversion part behind the scenes.  New users need to understand how data is stored and how to properly convert one type to the other, including lengths and associated truncation.  Its a bit like proc import/export, these functions work, and behind the scenes try to guess what you want to do.  Hence the constant stream of questions on here asking why x column is doing this, and why y file is not importing etc.  If they learnt how to import a file by hand typing everything in, setting formats/informats/lengths, and also how to design transfer specifications, then these questions would not arise as they would understand the principals.  Most specifications I have seen state lengths of numeric variables including how many decimal places, so as long as you follow spec then there shouldn't be any problems. 

Mind you, I suppose you could take that argument right back to why we are not programming in assembly, but hey, just trying to reduce the numbers of questions.

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

It depends on the crowd. A good proportion of the people I work with are not programmers. They mostly use just SQL and they always forget how to convert types. That's probably the #1 question they keep asking. Or used to be.

I wrote a to_number() function à la oracle for them for the same reason.

But I use cat() too: why bother with put(NUM, best32. -l) when it doesn't do a better job than cats (NUM)?

Sadly, we're moving onto EG soon though, so I suppose they'll like it better (we'll see how EG converts types) while the more confirmed SAS users will have to endure EG's interface (I know I know, many people here like EG for some reason I cannot fathom). SAS Studio will ease the pain somewhat.

Super User
Super User
Posts: 7,432

Re: Array processing - Numeric to Character Conversion using a put statement

"people I work with are not programmers" - I wouldn't let them do programming then (SQL is programming).  You wouldn't want me doing surgery would you?  Yes, tools like EG and VA are plasters, hide the code underneath so anyone can use them.  Sounds great, but in the UK at least there is a problem with people no longer understanding coding, just point an click.  Another example is tv's.  My partners nephew the other day was trying to press the tv screen, had grown up with ipad's so just didn't understand how things worked outside touch screens.

PROC Star
Posts: 1,570

Re: Array processing - Numeric to Character Conversion using a put statement

They are analysts, so they need to manipulate data. SQL is one step up from excel, and allows them to go to oracle as well. Full SAS programmation is another step up which only some climb. I feel your pain about users not always understanding what's happening ebhind the scene. Same about some "statisticians" ' models. EG was a curse in this respect, a double edged sword: more SAS users on one hand, more naive users on the other. EG should never had replaced the DMS. A good IDE should have replaced it: 2 crowds, 2 interfaces. Sadly SAS pushed EG like there's no tomorrow.

🔒 This topic is solved and locked.

Need further help from the community? Please ask a new question.

Discussion stats
  • 15 replies
  • 511 views
  • 0 likes
  • 4 in conversation