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

Hi, I am trying to create a table with variables col_1, col_2, col_3, to be reassigned to the values below, but for some reason they only show up as (%) with no numbers assigned to them. I have checked my bigcol variables and they do have values. Any advice is appreciated!

 

data num_prop ;
   retain rowlabel col_1 col_2 col_3 comnum ;
   merge num_prop bignumber;
   by comnum;
   rowlabel=' n(Proportion)';
   if col_1 ne '0(0.0)' then col_1=cat(strip(put(col_1, 8.0)),' (', strip(put((col_1/bigcol1)*100,8.1)) ,'%)');
   else col_1=col_1;
   if col_2 ne '0(0.0)' then col_2=cat(strip(put(col_2, 8.0)),' (', strip(put((col_2/bigcol2)*100,8.1)) ,'%)');
   else col_2=col_2;
   if col_3 ne '0(0.0)' then col_3=cat(strip(put(col_3, 8.0)),' (', strip(put((col_3/bigcol3)*100,8.1)) ,'%)');
   else col_3=col_3;
vorder=1;
roworder=3;
run;

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

@kmardinian,

 

This thread has gone on for so long that it's difficult to see that the issue has been identified a couple of times.  I'm just repeating part of what has already been said here (at least twice).  Consider this section of a DATA step:

 

col_1 = '5(25.0)';

bigcol1 = 1000;

ratio = col_1 / bigcol1;

 

What would you like the ratio to be?  Really, SAS doesn't decide.  It complains that "5(25.0)" isn't a number and cannot be used to perform math.  There may be a different way to perform math with this, but you first have to decide what the calculation for ratio should be.

View solution in original post

30 REPLIES 30
Kurt_Bremser
Super User

col_1 (and so on) seem to be character, and contain values which cannot automatically be converted to numbers. See the log for this (Maxim 2). Also see Maxim 3 (Know your data).

If that doesn't provide enough help, post the log (use the {i} button).

kmardinian
Quartz | Level 8

Thank you for your help, for some reason, now, nothing is showing up for all the col variables.

 

7930   data num_prop ;
7931   retain rowlabel col_1 col_2 col_3 comnum ;
7932   merge num_prop bignumber;
7933   numcol_1=input(col_1,best32.);
7934   numcol_2=input(col_2,best32.);
7935   numcol_3=input(col_3,best32.);
7936   drop col_1 col_2 col_3;
7937   rename numcol_1=col_1 numcol_2=col_2 numcol_3=col_3;
7938      by comnum;
7939      rowlabel=' n(Proportion)';
7940      if col_1 ne '0(0.0)' then col_1=cat(strip(put(col_1, 8.0)),' (', strip(put((col_1/bigcol1)*100,8.1)) ,'%)');
7941      else col_1=col_1;
7942      if col_2 ne '0(0.0)' then col_2=cat(strip(put(col_2, 8.0)),' (', strip(put((col_2/bigcol2)*100,8.1)) ,'%)');
7943      else col_2=col_2;
7944      if col_3 ne '0(0.0)' then col_3=cat(strip(put(col_3, 8.0)),' (', strip(put((col_3/bigcol3)*100,8.1)) ,'%)');
7945      else col_3=col_3;
7946   vorder=1;
7947   roworder=3;
7948   run;

NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
      7940:80   7942:80   7944:80
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 7940:85   1 at 7940:94   1 at 7942:85   1 at 7942:94   1 at 7944:85   1 at 7944:94
NOTE: There were 0 observations read from the data set WORK.NUM_PROP.
NOTE: There were 1 observations read from the data set WORK.BIGNUMBER.
NOTE: The data set WORK.NUM_PROP has 1 observations and 13 variables.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds

Kurt_Bremser
Super User

@kmardinian wrote:

Thank you for your help, for some reason, now, nothing is showing up for all the col variables.

 

7930   data num_prop ;
7931   retain rowlabel col_1 col_2 col_3 comnum ;
7932   merge num_prop bignumber;
7933   numcol_1=input(col_1,best32.);
7934   numcol_2=input(col_2,best32.);
7935   numcol_3=input(col_3,best32.);
7936   drop col_1 col_2 col_3;
7937   rename numcol_1=col_1 numcol_2=col_2 numcol_3=col_3;
7938      by comnum;
7939      rowlabel=' n(Proportion)';
7940      if col_1 ne '0(0.0)' then col_1=cat(strip(put(col_1, 8.0)),' (', strip(put((col_1/bigcol1)*100,8.1)) ,'%)');
7941      else col_1=col_1;
7942      if col_2 ne '0(0.0)' then col_2=cat(strip(put(col_2, 8.0)),' (', strip(put((col_2/bigcol2)*100,8.1)) ,'%)');
7943      else col_2=col_2;
7944      if col_3 ne '0(0.0)' then col_3=cat(strip(put(col_3, 8.0)),' (', strip(put((col_3/bigcol3)*100,8.1)) ,'%)');
7945      else col_3=col_3;
7946   vorder=1;
7947   roworder=3;
7948   run;

NOTE: Character values have been converted to numeric values at the places given by: (Line):(Column).
      7940:80   7942:80   7944:80
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 7940:85   1 at 7940:94   1 at 7942:85   1 at 7942:94   1 at 7944:85   1 at 7944:94
NOTE: There were 0 observations read from the data set WORK.NUM_PROP.
NOTE: There were 1 observations read from the data set WORK.BIGNUMBER.
NOTE: The data set WORK.NUM_PROP has 1 observations and 13 variables.
NOTE: DATA statement used (Total process time):
      real time           0.02 seconds
      cpu time            0.01 seconds


There's lots of issues with your code and the way it is written.

 

retain rowlabel col_1 col_2 col_3 comnum ;

If (some of) these variables are contained in either num_prop or bignumber, they need not be retained. variables from datasets in a set or merge statement are automatically retained. Including them in a retain statement will only cause confusion.

drop col_1 col_2 col_3;
rename numcol_1=col_1 numcol_2=col_2 numcol_3=col_3;

I would not include such statements in the data step itself, but rather as dataset options for input and/or output datasets. That makes it clear when the rename or drop happens, and which names are active in the data step itself. Otherwise you might find later that you acted on non-existent variables, and the way you wrote the code prevented the data step compiler from issuing a "unititialized variable " NOTE.

 

Move the by statement up so that it follows the merge statement immediately. That makes it easier to read.

 

Use indentation consistently. In your code, then unmotivated indentation suggests a functional block that simply isn't there.

 

We've covered the impossibility of converting a string like '0(0.0)' to a number in other posts already.

Astounding
PROC Star

Here's a simplified version of your program (very simplified!) so you can experiment with it and see where you are going wrong:

 

data test;

col_1 = '5(25.0)';

col_1a = put(col_1, 8.0);

run;

 

Also note, even the strongest SAS programmers have to read the log and figure out what the notes mean, to diagnose a problem.  As a relative beginner, that's a habit you need to adopt.

ballardw
Super User

@Astounding wrote:

Here's a simplified version of your program (very simplified!) so you can experiment with it and see where you are going wrong:

 

data test;

col_1 = '5(25.0)';

col_1a = put(col_1, 8.0);

run;

 

Also note, even the strongest SAS programmers have to read the log and figure out what the notes mean, to diagnose a problem.  As a relative beginner, that's a habit you need to adopt.


@Astounding perhaps you also intended to include a: col_num = input(col_1,8.); or similar?

Astounding
PROC Star

@ballardw,

 

No, I meant to leave it as is.  I know it doesn't work.  

 

The original post seems to assume that the incoming variable COL_1 might contain "0(0.0)"

 

That's probably wrong, and in fact I'm not even sure that there is an incoming variable named COL_1.  There might be.  Even if there is, we don't really know if it's character or numeric.  So I pushed the question back to the original poster, to (I hope) force some learning about what is in the data, and what the issues are in getting the PUT function to work at all.

 

I'm not sure that is the best approach ... I just think it's a decent approach.

kmardinian
Quartz | Level 8

I added this below code to ensure that col variables are equal to '0(0.0%)' and I checked, the col variables are character. I already tried changing them to numeric and still doesn't work after that is done.

 

data num_prop;
   length rowlabel $100 col_1 col_2 col_3 col_4 $32 ;
   rowlabel='    n (Proportion)';
   col_1='0 (0.0%)';
   col_2='0 (0.0%)';
   col_3='0 (0.0%)';
   col_4='';
   roworder=3;
   vorder=1;
run;

data num_prop;
   set num_prop ;
   comnum=1;
run;

proc sort;
by comnum;
run;

data num_prop ;
   retain rowlabel col_1 col_2 col_3 comnum ;
   merge num_prop bignumber;
   by comnum;
   rowlabel=' n(Proportion)';
   if col_1 = '0(0.0)' then col_1=cat(strip(put(col_1, 32.0)),' (', strip(put((col_1/bigcol1)*100,8.1)) ,'%)');
   else col_1=col_1;
   if col_2 = '0(0.0)' then col_2=cat(strip(put(col_2, 8.0)),' (', strip(put((col_2/bigcol2)*100,8.1)) ,'%)');
   else col_2=col_2;
   if col_3 = '0(0.0)' then col_3=cat(strip(put(col_3, 8.0)),' (', strip(put((col_3/bigcol3)*100,8.1)) ,'%)');
   else col_3=col_3;
vorder=1;
roworder=3;
run;

kmardinian
Quartz | Level 8

I ran the test code and it works, it replaces col_1a with '5(25.0)' But I'm not sure what that tells me? That its not a problem with the variable, but the syntax in my code? Thanks for your help!

Astounding
PROC Star

Did the log really say nothing about using a character string and the 8.0 format?

 

You may need to experiment with a few variations, such as:

 

data test2;

col_1 = 'abcdefghijklmnop';

col_1a = put(col_1, 8.0);

run;

 

data test3;

col_1 = 20;

col_1a = put(col_1, 8.0);

run;

 

Start off by getting a feel for what the PUT function expects as input, and what it produces as output.

kmardinian
Quartz | Level 8

No, the log didn't list anything

 


13404
13405  data numprop;
13406
13407  col_1 = '5(25.0)';
13408
13409  col_1a = put(col_1, 8.0);
13410
13411  run;

NOTE: The data set WORK.NUMPROP has 1 observations and 2 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

I am going to play around with the put statement and see if I can figure it out. Thank you!

Astounding
PROC Star

That's unexpected (having no additional notes in the log), and a change in how SAS works.  

 

Here's a way to zero in on the problem, based on the notes you received earlier.

 

This is an invalid calculation:

 

col_1 = '5(25.0)';

bigcol1 = 1000;

ratio = col_1 / bigcol1;

 

There's no way to convert COL_1 to a legitimate number that can be used in a formula.

kmardinian
Quartz | Level 8

292  data numprop;
293
294  col_1 = '5(25.0)';
295  bigcol1=1000;
296  ratio=col_1/bigcol1;
297  run;

NOTE: Character values have been converted to numeric values at the places given by:
      (Line):(Column).
      296:7
NOTE: Invalid numeric data, col_1='5(25.0)' , at line 296 column 7.
col_1=5(25.0) bigcol1=1000 ratio=. _ERROR_=1 _N_=1
NOTE: Missing values were generated as a result of performing an operation on missing values.
      Each place is given by: (Number of times) at (Line):(Column).
      1 at 296:12
NOTE: The data set WORK.NUMPROP has 1 observations and 3 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds

 

So it converted col_1 to numeric, but seems to not like the format it's in?

Astounding
PROC Star

The note is saying that COL_1 can't really be converted to numeric.

 

What number would it be?  5?  25?  It just isn't a number.

 

If you would like to find the number before what is in parentheses, there are ways to do that.

kmardinian
Quartz | Level 8

When I check the dataset num_prop before I run that particular code. The col variable has this description:

Name:col_1

Label=^(N=21)

Format: $32

Type: Character.

 

with 3 Observations of 12, 9, 21

 

 

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
  • 30 replies
  • 1600 views
  • 0 likes
  • 5 in conversation