Search code examples
sashashtable

Numeric to numeric format


I have a invalue format to populate the value of VISITNUM for some records where it's value is missing using AVISITN which is populated for all records as a reference. Both are numeric variables. So if AVISITN = 10 I would want the missing VISITNUM to be 1 etc.

proc format;    
 
 invalue dummy_visnum
        10 = 1
        20 = 2        
        30 = 4
        40 = 5
        50 = 6
        60 = 7
        70 = 8
        80 = 9
        100= 10;
       

quit;

data have;
input VISITNUM :8. AVISITN :8.;
infile datalines dlm = '|';
datalines;
1|10|
2|20|
4|30|
5|40|
6|50|
7|60|
8|70|
1|10|
2|20|
4|30|
5|40|
6|50|
 |60|
 |70|
 |80|
1|10|
2|20|
4|30|
5|40|
 |50|
 |60|
 |70|
 |80|
1|10|
2|20|
 |30|
 |40|
 |50|
 |60|
 |70|
 |80|
;
RUN;

data want;
input VISITNUM :8. AVISITN :8.;
infile datalines dlm = '|';
datalines;
1|10|
2|20|
4|30|
5|40|
6|50|
7|60|
8|70|
1|10|
2|20|
4|30|
5|40|
6|50|
7|60|
8|70|
9|80|
1|10|
2|20|
4|30|
5|40|
6|50|
7|60|
8|70|
9|80|
1|10|
2|20|
4|30|
5|40|
6|50|
7|60|
8|70|
9|80|
 ;
RUN;

However when I run this code it works as intended but I get a warning in my log "Numeric values have been converted to character values at the places given by: (Line):(Column)."

 visitnum = input(avisitn, dummy_visnum.); 

"The VALUE statement in PROC FORMAT is used to define a FORMAT. The INVALUE statement is used to define an INFORMAT. In SAS you use a FORMAT to convert values into text and an INFORMAT to convert text into values." With INFORMAT, you are telling SAS that AVISITN Is text, but it is actually a number. Hence, SAS converts AVISITN into text. So i know this approach doesn't work because AVISITN is getting converted to text which is causing the warning in the log. So i could try something like this as an alternative

if missing(visitn) then visitn = avisitn / 10 or
visitnum = input(cats(mod(avisitn,10)),dummy_visnum.);

However, the data is slightly asynchronous as it does not have a one to one conversion as visitnum = 3 is AVISITN = 40 and same for VISITNUM 4 to 9. It is only 1,2 and 10 where this would work. Does anyone have any alternative suggestions? I seen a HASH Object data_null step using find but not sure this would work here.


Solution

  • ... and you can use an INFORMAT to convert text into numbers.

    So create a FORMAT that converts your numbers into strings that LOOK LIKE the numbers you want. You can then use a call to PUT() to convert the numbers into strings and pass the result to INPUT() to convert those strings into numbers.

    proc format ;
      value num2char 
        10 ='1'
        20 ='2'
        30 ='4'
        40 ='5'
        50 ='6'
        60 ='7'
        70 ='8'
        80 ='9'
      ;
    run;
    data want;
      set have;
      avistn = input(put(visitnum,num2char.),32.);
    run;