BookmarkSubscribeRSS Feed
chopra
Calcite | Level 5

I am trying to create a new variable using no. of character variables. But it is showing me this error.

 

My code is the following

 

data caries ;
set NH.OHXDEN_I;

if rescode = ' ' then rescode = '00000';

if rescode = . then rescode = 0;

if (OHX31CTC or OHX30CTC or OHX29CTC or OHX28CTC or OHX27CTC or OHX26CTC or OHX25CTC or OHX24CTC or OHX23CTC
or OHX22CTC or OHX21CTC or OHX20CTC or OHX19CTC or OHX18CTC or OHX15CTC or OHX14CTC or OHX13CTC or OHX12CTC
or OHX11CTC or OHX10CTC or OHX09CTC or OHX08CTC or OHX07CTC or OHX06CTC or OHX05CTC or OHX04CTC or OHX03CTC or OHX02CTC)
= 'F' then caries =1;

if (OHX31CTC or OHX30CTC or OHX29CTC or OHX28CTC or OHX27CTC or OHX26CTC or OHX25CTC or OHX24CTC or OHX23CTC
or OHX22CTC or OHX21CTC or OHX20CTC or OHX19CTC or OHX18CTC or OHX15CTC or OHX14CTC or OHX13CTC or OHX12CTC
or OHX11CTC or OHX10CTC or OHX09CTC or OHX08CTC or OHX07CTC or OHX06CTC or OHX05CTC or OHX04CTC or OHX03CTC or OHX02CTC)
= 'Z' then caries = 1 ;

ELSE CARIES= 0;

 

RUN;

 

This is the error it is showing. First it is converting character into numeric values and then back to character?

NOTE: Character values have been converted to numeric values at the places given by:
(Line):(Column).
654:4 656:5 656:17 656:29 656:41 656:53 656:65 656:77 656:89
656:101 657:4 657:16 657:28 657:40 657:52 657:64 657:76 657:88
657:100 658:4 658:16 658:28 658:40 658:52 658:64 658:76 658:88
658:100 658:112 659:3 661:5 661:17 661:29 661:41 661:53 661:65
661:77 661:89 661:101 662:4 662:16 662:28 662:40 662:52 662:64
662:76 662:88 662:100 663:4 663:16 663:28 663:40 663:52 663:64
663:76 663:88 663:100 663:112 664:3
NOTE: Numeric values have been converted to character values at the places given by:
(Line):(Column).
654:31
NOTE: Invalid numeric data, OHX31CTC='F' , at line 656 column 5.
NOTE: Invalid numeric data, OHX30CTC='F' , at line 656 column 17.
NOTE: Invalid numeric data, OHX29CTC='S' , at line 656 column 29.
NOTE: Invalid numeric data, OHX28CTC='S' , at line 656 column 41.
NOTE: Invalid numeric data, OHX27CTC='F' , at line 656 column 53.
NOTE: Invalid numeric data, OHX26CTC='S' , at line 656 column 65.
NOTE: Invalid numeric data, OHX25CTC='S' , at line 656 column 77.
NOTE: Invalid numeric data, OHX24CTC='S' , at line 656 column 89.
NOTE: Invalid numeric data, OHX23CTC='S' , at line 656 column 10

4 REPLIES 4
kiranv_
Rhodochrosite | Level 12

if rescode = ' ' then rescode = '00000';

if rescode = . then rescode = 0;

 

for the same variable you have defined character and numeric 

 

probably you do not need

 

if rescode = . then rescode = 0;

 

and also

 

data class;
set sashelp.class;
gender = sex;
run;


data class2;
set class;
/* you have this */
if (sex or gender) ='F';
/* change it to below or change it to array*/
if sex ='M' or sex ='F';
run;

 

ballardw
Super User

@chopra wrote:

I am trying to create a new variable using no. of character variables. But it is showing me this error.

 

My code is the following

 

data caries ;
set NH.OHXDEN_I;

if rescode = ' ' then rescode = '00000';

if rescode = . then rescode = 0;

if (OHX31CTC or OHX30CTC or OHX29CTC or OHX28CTC or OHX27CTC or OHX26CTC or OHX25CTC or OHX24CTC or OHX23CTC
or OHX22CTC or OHX21CTC or OHX20CTC or OHX19CTC or OHX18CTC or OHX15CTC or OHX14CTC or OHX13CTC or OHX12CTC
or OHX11CTC or OHX10CTC or OHX09CTC or OHX08CTC or OHX07CTC or OHX06CTC or OHX05CTC or OHX04CTC or OHX03CTC or OHX02CTC)
= 'F' then caries =1;

if (OHX31CTC or OHX30CTC or OHX29CTC or OHX28CTC or OHX27CTC or OHX26CTC or OHX25CTC or OHX24CTC or OHX23CTC
or OHX22CTC or OHX21CTC or OHX20CTC or OHX19CTC or OHX18CTC or OHX15CTC or OHX14CTC or OHX13CTC or OHX12CTC
or OHX11CTC or OHX10CTC or OHX09CTC or OHX08CTC or OHX07CTC or OHX06CTC or OHX05CTC or OHX04CTC or OHX03CTC or OHX02CTC)
= 'Z' then caries = 1 ;

ELSE CARIES= 0;

 

RUN;

 

This is the error it is showing. First it is converting character into numeric values and then back to character?

NOTE: Character values have been converted to numeric values at the places given by:
(Line):(Column).
654:4 656:5 656:17 656:29 656:41 656:53 656:65 656:77 656:89
656:101 657:4 657:16 657:28 657:40 657:52 657:64 657:76 657:88
657:100 658:4 658:16 658:28 658:40 658:52 658:64 658:76 658:88
658:100 658:112 659:3 661:5 661:17 661:29 661:41 661:53 661:65
661:77 661:89 661:101 662:4 662:16 662:28 662:40 662:52 662:64
662:76 662:88 662:100 663:4 663:16 663:28 663:40 663:52 663:64
663:76 663:88 663:100 663:112 664:3
NOTE: Numeric values have been converted to character values at the places given by:
(Line):(Column).
654:31
NOTE: Invalid numeric data, OHX31CTC='F' , at line 656 column 5.
NOTE: Invalid numeric data, OHX30CTC='F' , at line 656 column 17.
NOTE: Invalid numeric data, OHX29CTC='S' , at line 656 column 29.
NOTE: Invalid numeric data, OHX28CTC='S' , at line 656 column 41.
NOTE: Invalid numeric data, OHX27CTC='F' , at line 656 column 53.
NOTE: Invalid numeric data, OHX26CTC='S' , at line 656 column 65.
NOTE: Invalid numeric data, OHX25CTC='S' , at line 656 column 77.
NOTE: Invalid numeric data, OHX24CTC='S' , at line 656 column 89.
NOTE: Invalid numeric data, OHX23CTC='S' , at line 656 column 10


If by this code you intend to compare all of the variables to the value of 'F' then it is way off. The construct of (thisvar or thatvar) or any number of variables inside the ( ) with 'or' will attempt to treat each of the variables as Boolean (normally numeric 0 or 1 values) and then yield a single true or false value which SAS will treat as numeric 1 or 0 for that comparison. Since at least some of your variables are character that are not convertible to valid numeric values you get the error. Note that the result of the comparisons will ever equal 'F' as OR returns 1 and 0.

if (OHX31CTC or OHX30CTC or OHX29CTC or OHX28CTC or OHX27CTC or OHX26CTC or OHX25CTC or OHX24CTC or OHX23CTC
or OHX22CTC or OHX21CTC or OHX20CTC or OHX19CTC or OHX18CTC or OHX15CTC or OHX14CTC or OHX13CTC or OHX12CTC
or OHX11CTC or OHX10CTC or OHX09CTC or OHX08CTC or OHX07CTC or OHX06CTC or OHX05CTC or OHX04CTC or OHX03CTC or OHX02CTC)
= 'F' then caries =1;

Without seeing more complete descriptions of the possible values for all of those CTC values I cannot be sure of a best comparison. If each of the values consists of a single character then perhaps

 

if index( cats(OHX31CTC,OHX30CTC,OHX29CTC,OHX28CTC,OHX27CTC,OHX26CTC,OHX25CTC,OHX24CTC,OHX23CTC
         ,OHX22CTC,OHX21CTC,OHX20CTC,OHX19CTC,OHX18CTC,OHX15CTC,OHX14CTC,OHX13CTC,OHX12CTC
         ,OHX11CTC,OHX10CTC,OHX09CTC,OHX08CTC,OHX07CTC,OHX06CTC,OHX05CTC,OHX04CTC,OHX03CTC,OHX02CTC),'F')>0 then caries =1;

will do what you intended. The CATS function makes a single string of all of the variables and the INDEX function returns a value of 1 or greater if F is found in the result. The actual value would be the position of the letter 'F' in the string.

 

Likely you want something similar in the comparison for Z.

 

See this as example of invalid character to numeric and valid character to numeric:

data example;
   x='A';
   y='B';
   z=(x or y);
run;
data example2;
   x='0';
   y='1';
   z=(x or y);
run;
chopra
Calcite | Level 5

@ballardwThank you for your reply.

 

I think you are right. My data set looks something like this. Where i have 32 character variables, who have values A,Z,E,D and so on. They are joined using the ID no. of each individual. The values do consist of a single character

 

The code that you provided above gives me the number of Sequence Id who have A or Z. How do I put in the code for the number who dont have it. I used this-

data caries;
set nh.ohxden_i;

if index( cats(OHX31CTC,OHX30CTC,OHX29CTC,OHX28CTC,OHX27CTC,OHX26CTC,OHX25CTC,OHX24CTC,OHX23CTC
,OHX22CTC,OHX21CTC,OHX20CTC,OHX19CTC,OHX18CTC,OHX15CTC,OHX14CTC,OHX13CTC,OHX12CTC
,OHX11CTC,OHX10CTC,OHX09CTC,OHX08CTC,OHX07CTC,OHX06CTC,OHX05CTC,OHX04CTC,OHX03CTC,OHX02CTC),'F')>0 then caries =1;

if index( cats(OHX31CTC,OHX30CTC,OHX29CTC,OHX28CTC,OHX27CTC,OHX26CTC,OHX25CTC,OHX24CTC,OHX23CTC
,OHX22CTC,OHX21CTC,OHX20CTC,OHX19CTC,OHX18CTC,OHX15CTC,OHX14CTC,OHX13CTC,OHX12CTC
,OHX11CTC,OHX10CTC,OHX09CTC,OHX08CTC,OHX07CTC,OHX06CTC,OHX05CTC,OHX04CTC,OHX03CTC,OHX02CTC),'Z')>0 then caries =1;

if index( cats(OHX31CTC,OHX30CTC,OHX29CTC,OHX28CTC,OHX27CTC,OHX26CTC,OHX25CTC,OHX24CTC,OHX23CTC
,OHX22CTC,OHX21CTC,OHX20CTC,OHX19CTC,OHX18CTC,OHX15CTC,OHX14CTC,OHX13CTC,OHX12CTC
,OHX11CTC,OHX10CTC,OHX09CTC,OHX08CTC,OHX07CTC,OHX06CTC,OHX05CTC,OHX04CTC,OHX03CTC,OHX02CTC),'A')>0 then caries =1;

RUN;

 

Can I just put else caries = 0 at the end of the code, to obtain the no. of individuals who do not have Z,F or A as their value

 

ballardw
Super User

@chopra wrote:

@ballardwThank you for your reply.

 

I think you are right. My data set looks something like this. Where i have 32 character variables, who have values A,Z,E,D and so on. They are joined using the ID no. of each individual. The values do consist of a single character

 

The code that you provided above gives me the number of Sequence Id who have A or Z. How do I put in the code for the number who dont have it.


On generic approach is IF/then/ Else.

 

If <condition> then caries=1;

Else if <another condition> then caries=1;

else if <different condition> then caries=1;

else caries = 0;

 

If you have a whole lot of these that you are searching for specific values then an array may be what you want as there is a function WHICHC (or WHICHN when looking for numeric values) which returns which variable matches (equals) the value or 0 if not found. I didn't recommend this first as I was not sure you might not have been looking for an "F" that occurred in "FX" in a single variable for instance.

data example;
   input a $ b $ c $;
   array z a b c;
   Fpos = whichc('F',of z(*));
datalines;
F F F
X X X
Z E D
;
run;

So you could also use

 

If whichc('F', of array(*))>0 then  caries=1; which would then tie back to the If/then/else and have somewhat easier on the eyes code.

The "of array(*)" construct is available for many functions that take multiple parameters and places all of the current values of the array into the function. Cats( of array(*)) for instance will work.

 

So adding a statement such as

array ohx OHX31CTC OHX30CTC OHX29CTC OHX28CTC OHX27CTC OHX26CTC OHX25CTC OHX24CTC OHX23CTC
 OHX22CTC OHX21CTC OHX20CTC OHX19CTC OHX18CTC OHX15CTC OHX14CTC OHX13CTC OHX12CTC
 OHX11CTC OHX10CTC OHX09CTC OHX08CTC OHX07CTC OHX06CTC OHX05CTC OHX04CTC OHX03CTC OHX02CTC
;

and use of the array named ohx may help.

 

Since WHICHC returns a numeric position you might consider the order of the variables if you need a search done in a specific order as WHICHC returns the position of the first found match.

Note that many long term SAS programmers would have created variables names as OHXCTC31 etc as then the array array statement (or other shorthand lists) could use OHXCTC02 - OHXCTC31 or even just OHXCTC:  (note the colon );

 

BTW I kind of would expect an OHX01CTC and OHX32CTC since caries implies something with dental processes to me and generally 32 teeth.

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 4 replies
  • 1802 views
  • 0 likes
  • 3 in conversation