convert character variable to time in SAS - sas

I have a variable called post_time which is of character type
Type : Character
Length : 5
Foramt : $5.
Informat : $5.
eg: 00300 ,01250
How do I get time from this? can someone pls help me out?
need the time to look like 03:00AM 12:50PM
Need to display all the time in standard time zone

SAS will work directly with this via the HHMMSS informat.
data _null_;
x = input('02100',HHMMSS5.);
put x= timeampm9.;
run;
Any time zone concerns can be handled using either a time zone sensitive format, such as NLDATMTZ., and/or the TZONES2U or TZONEU2S functions, which work with DATETIME but may be able to work with your time values if you never go across a date boundary (though using timezones that's risky).
See the SAS Documentation page on Timezones for a more detailed explanation.

Assuming that the first three digits are hours and last two are minutes this may work:
data have;
input time $;
cards;
00300
00400
00234
;
run;
data want;
set have;
time_var=hms(
input(substr(time, 1,3), 3.),
input(substr(time, 4,2), 2.),
0);
format time_var timeampm8.;
run;

Related

how to read date and time from txt file using sas

I'm very new to SAS and I'm trying to read a txt file that contains date and time. The file is shown in the following figure
I believe I have tried all the possible options that I can think of to read the file but the output is still in numeric form. The following is the code I'm using
data wb_bg_1619;
infile "C:\Users\daizh\Desktop\Ren\SAS\wb_bg_0215.txt" firstobs=3 missover;
informat DATE DATE7. TIME TIME5. ;
input DATE TIME BG;
run;
proc print data=wb_bg_1619;
run;
The output looks like this
You've used an informat to automatically convert a date stored as text into a numeric SAS date format, which is the number of days since Jan 1 1960. To display that in a human readable format, you need to use a regular format. Add the following to the top or bottom of your code:
format date date9.
time time.
;
This changes how the data is displayed to you, but does not change how SAS works with it. As far as SAS is concerned, a date is only a number. You could run the rest of your program without ever using a format and get the right numbers and calculations with it if you wanted to, but that sure makes troubleshooting hard.
To remember the difference between a format and informat:
informats are for inputs
formats are for you

How to categorize a date by decade in SAS

I have a dataset with many dates in them. I want to categorize these dates into a new column that organizes them by decade (1980s, 1990s, etc).
I have a good idea on how to use IF, AND, and ELSE statements to accomplish this, but I don't know how to have SAS extract the year and only the year from the date to apply it to the conditional logic.
You could always use multipliers and the intnx() function as well.
Using Allan's sample data...
data want;
set have;
decade=year(intnx('year10.',dateval,0,'beginning'));
run;
The intnx() part of the code returns the date corresponding to the start of the decade, then we just take the year portion from it.
The year10. parameter tells it we want to work with decades, the 0 parameter means shift the date supplied to the current decade, and the beginning parameter tells it to return the date corresponding to the beginning of the decade.
If you're not familiar with using intnx() to perform date calculations in SAS see here for a quick primer: https://stackoverflow.com/a/11211180/214994
No need for conditional logic - can use a combination of the year() and floor() functions with some simple arithmetic:
data have;
infile cards;
input dateval date9.;
cards;
01JAN2004
08FEB1996
07MAR1987
14SEP1982
;run;
data want;
set have;
decade=floor(year(dateval)/10)*10;
run;
Which gives:

SAS Transpose Comma Separated Field

This is a follow-up to an earlier question of mine.
Transposing Comma-delimited field
The answer I got worked for the specific case, but now I have a much larger dataset, so reading it in a datalines statement is not an option. I have a dataset similar to the one created by this process:
data MAIN;
input ID STATUS STATE $;
cards;
123 7 AL,NC,SC,NY
456 6 AL,NC
789 7 ALL
;
run;
There are two problems here:
1: I need a separate row for each state in the STATE column
2: Notice the third observation says 'ALL'. I need to replace that with a list of the specific states, which I can get from a separate dataset (below).
data STATES;
input STATE $;
cards;
AL
NC
SC
NY
TX
;
run;
So, here is the process I am attempting that doesn't seem to be working.
First, I create a list of the STATES needed for the imputation, and a count of said states.
proc sql;
select distinct STATE into :all_states separated by ','
from STATES;
select count(distinct STATE) into :count_states
from STATES;
quit;
Second, I try to impute that list where the 'ALL' value appears for STATE. This is where the first error appears. How can I ensure that the variable STATE is long enough for the new value? Also, how do I handle the commas?
data x_MAIN;
set MAIN;
if STATE='ALL' then STATE="&all_states.";
run;
Finally, I use a SCAN function to read in one state at a time. I'm also getting an error here, but I think fixing the above part may solve it.
data x_MAIN_mod;
set x_MAIN;
array state(&count_states.) state:;
do i=1 to dim(state);
state(i) = scan(STATE,i,',');
end;
run;
Thanks in advance for the help!
Looks like you are almost there. Try this on the last Data Step.
data x_MAIN_mod;
set x_MAIN;
format out_state $2.;
nstate = countw(state,",");
do i=1 to nstate;
out_state = scan(state,i,",");
output;
end;
run;
Do you have to actually have two steps like that? You can use a 'big number' in a temporary variable and not have much effect on things, if you don't have the intermediate dataset.
data x_MAIN;
length state_temp $150;
set MAIN;
if STATE='ALL' then STATE_temp="&all_states.";
else STATE_temp=STATE;
array state(&count_states.) state:;
do i=1 to dim(state);
state(i) = scan(STATE,i,',');
end;
drop STATE_temp;
run;
If you actually do need the STATE, then honestly I'd go with the big number (=50*3, so not all that big) and then add OPTIONS COMPRESS=CHAR; which will (give or take) turn your CHAR fields into VARCHAR (at the cost of a tiny bit of CPU time, but usually far less than the disk read/write time saved).

How to read excel files containing brackets in header in sas?

I have an excel file where open of the columns is temperature (F) and then when I import it in sas it saves variable name as temperature_F_ or when I use validvarany option it saves exactly as temperature (F). However, I need to now convert the data in C. So whenever I use either of the variable name (i.e temperature_F_ or temperature (F)) it does not work. For the second one, it thinks temperature as functions. So wats the way around this one?
The exact nature of your problem isn't clear, as temperature_F_ should be fine if you've imported under validvarname=v7.
data want;
set have;
temperature_c_ = (5/9)*((temperature_f_)-32);
run;
If you have to work with the validvarname=any; version, then you use named literals:
data want;
set have;
'temperature(c)'n = (5/9)*(('temperature(f)'n)-32);
run;
Similar to a date literal (ie, '01JAN2010'd) but for member/variable/etc. names.

Converting number into dates

I have this number 90724 which is actually 24/07/2009, how can output the number to that date format. Another example 100821 should 21/08/2010
data want
set testData;
format date ddmmyyyy.;
run;
Cheers
You really need to learn about Informats. Another good introductory source is this UCLA site
What you really needed to specify is the format in which you have the dates - using the informat yymmdd6. It uses a YearCutOff option to determine which century a 2-digit year falls into see Adjusting Dates in a New Century & YEARCUTOFF= System Option
Note: The default is 1920 which spans the 100-year range between 1920 and 2019 - if your dates are outside this range then set the appropritate cutoff value using OPTIONS YEARCUTOFF=nnnn;
data test;
dateNumber=100821; ProperDate=input(put(dateNumber,6.), yymmdd6.); output;/*ProperDate= 21AUG2010*/
dateNumber=90724; ProperDate=input(put(dateNumber,6.) , yymmdd6.); output;/*ProperDate=24JUL2009*/
format ProperDate date9.;
run;