How to read year from timeseries?
Show older comments
Hi there,
I have a script that uses "eval" to define a range of yearly environmental values over a large number of sites for a large number of years. I know "eval" is not suggested, but with the number of years, sites, and variables I am dealing with it makes things a whole lot easier.
Anyways, the following snippet of code works well but I would like to automate it even more. In the following, I first load data then create a structure (pars_yr) that defines the variable years I am looking at.
% Download .DAT data matrix, define first column as datetime timeseries
%third column is temp. "Date_all_site" is the entire datetime column for that site.
% Data is recorded every 30min throughout the year
pars_site_yr = {'2014','2015','2016','2017','2018','2019'};
site_yr_start = min(Date_all_site):calyears(1):max(Date_all_site);
site_yrs = years(site_yr_start)
for i = 1:length(pars_site_yr)
eval(['temp_site_',pars_site_yr{i},' = site_',pars_yr{i},'(3,:);'])
end
% more of my code
The problem is, every time I add more data I need to manually change "pars_site_yr". This isn't a huge problem considering I will only need to do it once a year, but I think it would be cool if the code just automatically "read" the new datetime years (especially considering I already defined the years for each site in site_yrs).
"site_yrs" has all the years based off the input "Date_all_site", but it is not in a useable "structure" form like pars_site_yr is. Each site has a different range of years that data was recorded.
I'm pretty new to matlab so hopefully this is easy. Thanks a ton for all your help!
-Devon
5 Comments
Walter Roberson
on 28 Jan 2020
Edited: Walter Roberson
on 28 Jan 2020
Use a struct with dynamic field names instead of eval()
Devon Fisher-Chavez
on 28 Jan 2020
Walter Roberson
on 28 Jan 2020
for i = 1:length(pars_site_yr)
fn = ['y', pars_site_yr{i}];
temp_site.(fn) = site.(fn)(3,:);
end
This would expect site.y2014 site.y2015 and so on, and would produce temp_site.y2014 temp_site.y2015 and so on.
But often better is cell arrays (if the data is different lengths) or multidimensional numeric arrays when practical.
for i = 1:length(pars_site_yr)
fn = ['y', pars_site_yr{i}];
temp_site{i} = site.(fn)(3,:);
end
now you can cellfun over temp_site, and if you want to locate a particular year then ismember() into pars_site_yr and take the second output.
During the time that you are doing the processing, using variable names or struct field names that contain metadata is mostly for presentation purposes. Sometimes it can make sense to use metadata in struct field names inside .mat files but that is the last processing step and can often be handled with cell2struct()
Mohammad Sami
on 29 Jan 2020
Edited: Mohammad Sami
on 29 Jan 2020
Assuming a datetime variable. you can use year function
yr = year(datetime_var);
yr = unique(yr); % this will give you all the years in your data.
pars_site_yr = arrayfun(@num2str,yr,'UniformOutput',false);
Devon Fisher-Chavez
on 29 Jan 2020
Answers (0)
Categories
Find more on Logical 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!