Is there a simple way to reference months from data in matlab time?

4 views (last 30 days)
I need to plot monthly averages for several years of data recorded every half hour for the entire year. I can specify months like this for each year, but is there a simpler way to do this? I need to do it for 5 years of data.
tm=data(:,1)+datenum(1904,1,1);
date=datevec(tm);
jan_96=find(tm>=datenum(1996,1,1) & tm<datenum(1996,2,1));
feb_96=find(tm>=datenum(1996,2,1) & tm<datenum(1996,3,1));
mar_96=find(tm>=datenum(1996,3,1) & tm<datenum(1996,4,1));
apr_96=find(tm>=datenum(1996,4,1) & tm<datenum(1996,5,1));
may_96=find(tm>=datenum(1996,5,1) & tm<datenum(1996,6,1));
jun_96=find(tm>=datenum(1996,6,1) & tm<datenum(1996,7,1));
jul_96=find(tm>=datenum(1996,7,1) & tm<datenum(1996,8,1));
aug_96=find(tm>=datenum(1996,8,1) & tm<datenum(1996,9,1));
sep_96=find(tm>=datenum(1996,9,1) & tm<datenum(1996,10,1));
oct_96=find(tm>=datenum(1996,10,1) & tm<datenum(1996,11,1));
nov_96=find(tm>=datenum(1996,11,1) & tm<datenum(1996,12,1));
dec_96=find(tm>=datenum(1996,12,1) & tm<=datenum(1996,12,31));
  1 Comment
Stephen23
Stephen23 on 7 Jul 2015
Creating lots of variables like that is very awkward, because it mixes up meta-data with the code. It clutters your workspace, and makes writing, fixing and altering programs more difficult. It would be much cleaner and neater to create one variable that contains all of that information.

Sign in to comment.

Answers (3)

David Young
David Young on 7 Jul 2015
Edited: David Young on 7 Jul 2015
Using the attached function, you can do this:
[isplit, ~, meantime] = splitTimes(tm, 'month'); % get start and end point of each month
for m = 1:size(isplit, 2)
meantemp(m) = mean( temp(isplit(1,m):isplit(2,m)) );
end
plot(meantime, meantemp);
datetick('x');
where temp is your input series of temperatures, the same length as tm, and meantime and meantemp are vectors of monthly means of observation time and temperature.
I haven't got your data so this isn't tested - let me know if you run into a problem.

Stephen23
Stephen23 on 7 Jul 2015
You do not provide any sample data for us to work with, which means we have to invent our own. Try this:
% Sample data and dates:
inp_date = [2010,10,5;2010,10,6;2010,10,7;2011,3,30;2011,3,31]
inp_data = 1:size(inp_date,1)
num_date = datenum(inp_date);
% Make range of months covering all sample dates:
min_max = datevec([min(num_date);max(num_date)]);
new_date(:,2) = min_max(1,2) + (0:12*diff(min_max(:,1))+min_max(2,2)-min_max(1,2)+1);
new_date(:,1) = min_max(1,1);
new_date(:,3) = 1;
new_num = datenum(new_date);
datevec(new_num) % <- just for demo, not required!
% Locate each date within one month:
min_max = bsxfun(@ge,num_date,new_num(1:end-1).') & bsxfun(@lt,num_date,new_num(2:end).');
[~,col] = find(min_max);
% Mean of data within each month:
out = accumarray(col,inp_data,[],@mean)
Which displays this in the command window:
inp_date =
2010 10 5
2010 10 6
2010 10 7
2011 3 30
2011 3 31
inp_data =
1 2 3 4 5
ans =
2010 10 1 0 0 0
2010 11 1 0 0 0
2010 12 1 0 0 0
2011 1 1 0 0 0
2011 2 1 0 0 0
2011 3 1 0 0 0
2011 4 1 0 0 0
out =
2.0000
0
0
0
0
4.5000
It has successfully grouped the values of inp_data according to the corresponding dates of inp_date, and calculated the means of each group.

Steven Lord
Steven Lord on 7 Jul 2015
I would use datetimes rather than serial date numbers.
% Let's start on January 1st of the current year
todayDate = datetime('today');
startDate = dateshift(todayDate, 'start', 'year');
% We want the last day of the current year
endDate = dateshift(todayDate, 'end', 'year');
% Generate a list of random days between startDate and endDate
randomDays = days(randi([0, days(endDate-startDate)], 10, 1))+startDate;
% Let's display them as day-month-year
randomDays.Format = 'dd-MMM-yyyy';
% In which month is each date located?
M = month(randomDays);
% Display the dates and the number of the month in which each occurs in a table
T = table(randomDays, M, 'VariableNames', {'Dates', 'MonthNumber'})
If you don't like the arithmetic involved in computing randomDays above, you could instead generate all the candidate days then select a subset (use RANDI to select with replacement, RANDPERM to select without replacement.)
allDays = (startDate:endDate).';
selection = randi(numel(allDays), 10, 1);
randomDays = allDays(selection);

Categories

Find more on Dates and Time in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!