How to write dates (MM/DD/YY) into a matrix (SAS) - matrix

I have following problem:
I need to write a begin and end date into a matrix. Where the matrix contains the yearly quarters (1-4) in the collumns and the rows are the year.
E.g.
Matrix:
Q1 Q2 Q3 Q4
2010
2011
Now the Date 01.01.2010 should be put in the first element and the date 09.20.2011 in the sixed element.
Thanks in advance.

You first have to consider that SAS does not actually have date/time/datetime variables. It just uses numeric variables formatted as date/time/datetime. The actual value being:
days since 1/1/1960 for dates
seconds since 00:00 for times
seconds since 1/1/1960 00:00 for datetimes
SAS does not even distinguish between integer and float numeric types. So a date value can contain a fractional part.
What you do or can do with a SAS numeric variable is completely up to you, and mostly depends on the format you apply. You could mistakenly format a variable containing a date value with a datetime format... or even with a currency format... SAS won't notice or complain.
You also have to consider that SAS does not even actually have matrixes and arrays. It does provide a way to simulate their use to read and write to dataset variables.
That said, SAS does provide a whole lot of formats and informats that allow you to implement date and time manipulation.
Assuming you are coding within a data step, and assuming the "dates" are in dataset numeric variables, then the PUT function can extract the datepart you need to calculate row, column of the matrix element to write to, like so:
DATA table;
ARRAY dm{2,4} dm_r1c1-dm_r1c4 dm_r2c1-dm_r2c4;
beg_row = PUT(beg_date, YEAR4.)-2009;
end_row = PUT(end_date, YEAR4.)-2009;
beg_col = PUT(beg_date, QTR1.);
end_col = PUT(end_date, QTR1.);
dm{beg_row,beg_col} = beg_date;
dm{end_row,end_col} = end_date;
RUN;
... or if you are using a one-dimensional array:
DATA table;
ARRAY da{8} da_1-da_8;
beg_index = 4 * (PUT(beg_date, YEAR4.)-2010) + PUT(beg_date, QTR1.);
end_index = 4 * (PUT(end_date, YEAR4.)-2010) + PUT(end_date, QTR1.);
da{beg_index} = beg_date;
da{end_index} = end_date;
RUN;

Related

Subtract time in text format

I have two columns in excel and want to subtract the time difference in minutes
21/12/2022, 8:17 pm
21/12/2022, 8:00 pm
How can I convert text to a number format so that I can subtract those easily
You can use the VALUE function. The VALUE function converts a text string that represents a number to a number value.
For example, to convert the text "8:17" to a number value, you can use the following formula:
=VALUE("8:17")
This will return a number value equivalent to the time 8:17.
To subtract the time difference between two cells in Excel, you can use the =B2-A2 formula, where A2 and B2 are the cells containing the two times you want to subtract.
You can also use the =TEXT function to convert the result of the subtraction back to a text string in a desired format, if needed. For example, to convert the result to a time format, you can use the following formula:
=TEXT(B2-A2, "h:mm")
This will return the time difference in the format "hh:mm".

How to format time in SAS

I have a dataset with three columns : Start, Stop and Date
Observations in my Start and Stop are time type.
I have the following two values in my Start and Stop columns:
24:49:00 and 25:16:00
As there are both over 24 hours format.
I would like to convert those two values to the following:
24:49:00 to 00:49:00
and
25:16:00 to 01:16:00
How to do this in both SAS and proc sql ?
Thank you !
Do you need to convert them? Use the TIMEPART() function.
start_day=datepart(start);
start_time=timepart(start);
format start_time tod8.;
Or do you just want to display them that way?
format start stop tod8.;
Start/Stop time-24:00:00 like this:
data _null_;
start='25:16:14't;
point='24:00:00't;
_start=start-point;
put _start;
format _start time8.;
run;
SAS Time and DateTime values use seconds as their fundamental unit.
Thus you can use either modulus arithmetic or TIMEPART function to extract the less than 24 hour part of a > 24 hour time value.
data have;
start = '24:49:00't;
stop = '25:16:00't;
start_remainder = mod(start, '24:00't); * modulus arithmetic;
stop_remainder = mod(stop, '24:00't);
start_timepart = timepart(start); * TIMEPART function;
stop_timepart = timepart(stop);
format start: stop: time10.;
run;
After the computation do not expect start_remainder is less than stop_remainder to be always true.

Date format in VFP

Hi I have this query in VFP however I don't understand the meaning of it
REPLACE ALL varA WITH YEAR(varB)*100+MONTH(varB)
Can anyone explain why YEAR(varB) is multiply by 100?
Not at a PC to check but it looks like command will store yyyymm as a number. To achieve this, the command will store the year *100 (e.g. 202000) + month (e.g. 10 for October) = 202010. VarA stores a combination of date varB's year() and month () functions, both which return numbers.

How to change format to a single cell in a SAS table

I have to change format to a single cell in a SAS table. That is, the column where the cell is, has format best12., while given that in the cell there is a date, for it I want to use YYMMDD10.
How can I fix?
Thanks in advance.
You can only associate a FORMAT with entire column. If you want cells that have mixed type formatted differently you need a character column that put PUT (function) values into.
To associate a different format with a column use.
proc datasets;
modify data-set-name;
format variables new-format.;
run;
quit;
Here is an example of what you can do if the data allows. Let's say that the earliest date in your data is 1st Jan 2000, this is stored as the number 14,610 in SAS (the number of days since 1st Jan 1960). Therefore if no non-date values exceed this number then you can achieve your goal by formatting all values up to 14,610 as best12. and all values greater than this as yymmdd10.
proc format;
value dtfmt low - 14609 = [best12.]
14610 - high = [yymmdd10.]
;
run;
data want;
input num;
format num dtfmt.;
datalines;
10
20
20514
30
;
run;
You can apply SUBSTR() in IF condition to check for first character and format your variable accordingly..using INPUT() or PUT()

calculate standard deviation of daily data within a year

I have a question,
In Matlab, I have a vector of 20 years of daily data (X) and a vector of the relevant dates (DATES). In order to find the mean value of the daily data per year, I use the following script:
A = fints(DATES,X); %convert to financial time series
B = toannual(A,'CalcMethod', 'SimpAvg'); %calculate average value per year
C = fts2mat(B); %Convert fts object to vector
C is a vector of 20 values. showing the average value of the daily data for each of the 20 years. So far, so good.. Now I am trying to do the same thing but instead of calculating mean values annually, i need to calculate std annually but it seems there is not such an option with function "toannual".
Any ideas on how to do this?
THANK YOU IN ADVANCE
I'm assuming that X is the financial information and it is an even distribution across each year. You'll have to modify this if that isn't the case. Just to clarify, by even distribution, I mean that if there are 20 years and X has 200 values, each year has 10 values to it.
You should be able to do something like this:
num_years = length(C);
span_size = length(X)/num_years;
for n = 0:num_years-1
std_dev(n+1,1) = std(X(1+(n*span_size):(n+1)*span_size));
end
The idea is that you simply pass the date for the given year (the day to day values) into matlab's standard deviation function. That will return the std-dev for that year. std_dev should be a column vector that correlates 1:1 with your C vector of yearly averages.
unique_Dates = unique(DATES) %This should return a vector of 20 elements since you have 20 years.
std_dev = zeros(size(unique_Dates)); %Just pre allocating the standard deviation vector.
for n = 1:length(unique_Dates)
std_dev(n) = std(X(DATES==unique_Dates(n)));
end
Now this is assuming that your DATES matrix is passable to the unique function and that it will return the expected list of dates. If you have the dates in a numeric form I know this will work, I'm just concerned about the dates being in a string form.
In the event they are in a string form you can look at using regexp to parse the information and replace matching dates with a numeric identifier and use the above code. Or you can take the basic theory behind this and adapt it to what works best for you!

Resources