Hello. I am trying to use a time variable in an if-then statement. Please see example code below. The time is formatted as HHMM.
This code is not working due to the timevar portion. I understand that SAS doesn't store time in the formatted form. Is there a way to find out the equivalent values for my hours (i.e. 1,2,3,4...) and still use this code? Or some better way?
Thank you.
data want; set have;
if var1=1 and
(2=<timevar<3 and var2=-.09)
OR (3=<timevar<4 and var2<=-1.26)
OR (4=<timevar<5 and var2<=-1.54)
OR (5=<timevar<6 and var2<=-1.76)
then varwant=1; else varwant=0;
run;
@ScottBassyes, some version of that worked for me. Instead of days, I did hours. That provided a numeric variable (best12., not a time format) to use in the previous code. Thank you all!
data test;
set have;
select;
when ("00:00:00"t <= timevar < "01:00:00"t) hours=1;
when ("01:00:00"t <= timevar< "02:00:00"t) hours=2;
when ("02:00:00"t <= timevar< "03:00:00"t) hours=3;
when ("03:00:00"t <= timevar< "04:00:00"t) hours=4;
otherwise hours=-1; * representing "unknown" day ;
end;
run;
You probably want to use HOUR(timevar) in some form.
If you have a time like 13:45 then Hour function would return 13
This type of test
3=<timevar<4
would be
3 = hour(timevar)
If the time were 4:00 the hour would be 4. Hour( 3:59:59 ) would return 3.
The question might be though do you mean 1AM or 1PM? The SAS Hour function returns 0 to 23. 0 for time from midnight to 00:59:59 in the morning.
Thank you @ballardw. Actually, my timevar is age in hours for babies. The time goes from birth through 72 hours. Some of the values of my timevar, for example, are 69:15, 34:56, 3:45.
The solution you presented doesn't work for values over 24. Do you have any other suggestions?
Maybe turn the timevar to a numeric variable? Thank you.
The following will give you hours elapsed since birth (20may2019:10:30:00
) to current time in hh:mm:ss format
data _null_;
hours=(intck('seconds','20may2019:10:30:00'dt,datetime()));
format hours time12.;
put hours;
run;
Maybe turn the timevar to a numeric variable?
Time variables are numeric. They contain seconds. Unless it is a character variable. In which case you should convert to a number.
You didn't specify a "have" dataset, so I can only guess at representative values.
Does this work for you? Adjust as required:
data have;
input time time5.;
format time time8.;
datalines;
00:15
13:45
23:59
24:15
28:45
37:10
40:40
50:50
65:55
71:59
73:01
;
run;
data want1;
set have;
hour=hour(time); * so that doesn't work ;
format _all_; * shows you the internal value for your time column ;
run;
data want2;
set have;
select;
when ("00:00:00"t <= time < "24:00:00"t) day=1;
when ("24:00:00"t <= time < "48:00:00"t) day=2;
when ("48:00:00"t <= time < "72:00:00"t) day=3;
otherwise day=-1; * representing "unknown" day ;
end;
run;
See:
https://support.sas.com/documentation/cdl/en/lrcon/62955/HTML/default/viewer.htm#a000780334.htm
https://support.sas.com/documentation/cdl/en/lrcon/62955/HTML/default/viewer.htm#a002200738.htm
Note the 2nd link says:
SAS time value
is a value representing the number of seconds since midnight of the current day. SAS time values are between 0 and 86400.
IMO this is incorrect given the test case above.
@ScottBassyes, some version of that worked for me. Instead of days, I did hours. That provided a numeric variable (best12., not a time format) to use in the previous code. Thank you all!
data test;
set have;
select;
when ("00:00:00"t <= timevar < "01:00:00"t) hours=1;
when ("01:00:00"t <= timevar< "02:00:00"t) hours=2;
when ("02:00:00"t <= timevar< "03:00:00"t) hours=3;
when ("03:00:00"t <= timevar< "04:00:00"t) hours=4;
otherwise hours=-1; * representing "unknown" day ;
end;
run;
@eabc0351 wrote:
@ScottBassyes, some version of that worked for me. Instead of days, I did hours. That provided a numeric variable (best12., not a time format) to use in the previous code. Thank you all!
data test; set have; select; when ("00:00:00"t <= timevar < "01:00:00"t) hours=1; when ("01:00:00"t <= timevar< "02:00:00"t) hours=2; when ("02:00:00"t <= timevar< "03:00:00"t) hours=3; when ("03:00:00"t <= timevar< "04:00:00"t) hours=4; otherwise hours=-1; * representing "unknown" day ; end; run;
I did think of another approach which, depending on your circumstances, may be a better approach.
The above works fine for a small number of ranges (i.e. the three you specified), but gets problematic if the number of ranges increases.
Another approach is to create a range format. And, since formats can be created programatically via a cntlin dataset, you can easily create as many ranges as required.
Here is sample code. Hope this helps...
* for debugging: create a test format with high end exclusion ;
proc format;
value foo
1 - < 2=1
2 - < 3=2
;
run;
* for debugging: examine the format for the cntlout dataset ;
proc format cntlout=cntlout;
run;
* create a proc format cntlin dataset ;
data cntlin;
format fmtname type start end label; * this is just to set the PDV order and is optional ;
length fmtname $32 type $1 eexcl $1; * or this too could have set the PDV order ;
fmtname='time2hours';
type='N';
eexcl='Y';
start="00:00:00"t;
do label=0 to 72;
end=intnx('hour',start,1,'S');
output;
start=end;
end;
format start end time.;
run;
* for debugging only: show the actual (unformatted) values of start and end ;
proc print;
format _all_;
run;
* create the format ;
proc format cntlin=cntlin;
run;
/* a quick lesson on formats/informats:
formats: can accept either numeric or character input, always returns character output
informats: always accepts character input, returns either numeric or character output
I used a numeric format, so it accepts numeric input (time) but returns character output (hour)
So we will need to convert the output from character to numeric using the input function
*/
data test;
set cntlin;
hour=input(put(start,time2hours.),best.);
run;
That provided a numeric variable (best12., not a time format)
The time variables are always numeric, it is only the time format that makes it appear as a "time". There is no "best12." or "time." data type.
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.
Ready to level-up your skills? Choose your own adventure.