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;
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.
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).
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
@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.
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 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?
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.
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;
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!
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.
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!
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.
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?
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.
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
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.