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.
... 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;