Acquire annual data from table

2 views (last 30 days)
I am trying to calculate the annual cumulative freezing degree days from a dataset with air temperature observations. I came up with the below code, but the code 1) skips the final observation for each year and 2) the row index exceeds the table dimension. How can I better get the value for each year? And additionally is it also possible to get a value when the year is defined from july to june? I am using R2021b
T = readtable('RaaheNahkiainen.csv'); % skips the first row of data
T_f = -0.3; % freezing temperature
CFDD = zeros(T.Year(end) - T.Year(1) + 1,1); % annual cumulative freezing degree days to be filled
i = 2;
for j = 1:(T{end,1} - T{1,1} + 1)
while T{i,1} == T{i-1,1}
if T{i,6} < T_f
CFDD(j) = CFDD(j) + (T_f - T{i,6}) % add freezing degree days if temp is below freezing temperature
else
CFDD(j) = CFDD(j);
end
i = i + 1;
end
i = i + 1;
end
Thank you for your time!
  2 Comments
Florian van der Stap
Florian van der Stap on 16 Dec 2021
Thank you for your answer. Unfortuntaly when I use:
T = readtimetable('RaaheNahkiainen.csv');
I get an error saying:
Unable to detect datetime or duration data in file for row times.

Sign in to comment.

Accepted Answer

Adam Danz
Adam Danz on 16 Dec 2021
Edited: Adam Danz on 16 Dec 2021
Convert your table to a timetable,
T = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/836120/RaaheNahkiainen.csv');
Warning: Column headers from the file were modified to make them valid MATLAB identifiers before creating variable names for the table. The original column headers are saved in the VariableDescriptions property.
Set 'VariableNamingRule' to 'preserve' to use the original column headers as table variable names.
head(T) % Show sample
ans = 8×7 table
Year m d Time TimeZone AirTemperature_degC_ GroundMinimumTemperature_degC_ ____ __ _ ____ ________ ____________________ ______________________________ 1997 10 2 0 {'UTC'} 7.1 NaN 1997 10 3 0 {'UTC'} 6.8 NaN 1997 10 4 0 {'UTC'} 6.4 NaN 1997 10 5 0 {'UTC'} 5.2 NaN 1997 10 6 0 {'UTC'} 5.9 NaN 1997 10 7 0 {'UTC'} 6.3 NaN 1997 10 8 0 {'UTC'} 5.3 NaN 1997 10 9 0 {'UTC'} 4.2 NaN
dtm = datetime(T.Year, T.m, T.d); % Create datetime vector
TT = [timetable(dtm), T(:,5:end)]; % Create timetable
head(TT) % Show sample
ans = 8×3 timetable
dtm TimeZone AirTemperature_degC_ GroundMinimumTemperature_degC_ ___________ ________ ____________________ ______________________________ 02-Oct-1997 {'UTC'} 7.1 NaN 03-Oct-1997 {'UTC'} 6.8 NaN 04-Oct-1997 {'UTC'} 6.4 NaN 05-Oct-1997 {'UTC'} 5.2 NaN 06-Oct-1997 {'UTC'} 5.9 NaN 07-Oct-1997 {'UTC'} 6.3 NaN 08-Oct-1997 {'UTC'} 5.3 NaN 09-Oct-1997 {'UTC'} 4.2 NaN
Now apply retime to compute anual averages. Only pass numeric columns to retime.
isNumericColumn = varfun(@isnumeric, TT, 'OutputFormat','uniform');
TTavg = retime(TT(:,isNumericColumn),'yearly','mean')
TTavg = 25×2 timetable
dtm AirTemperature_degC_ GroundMinimumTemperature_degC_ ___________ ____________________ ______________________________ 01-Jan-1997 0.041758 NaN 01-Jan-1998 2.4402 NaN 01-Jan-1999 3.3825 NaN 01-Jan-2000 4.4366 NaN 01-Jan-2001 2.2332 NaN 01-Jan-2002 4.3782 NaN 01-Jan-2003 3.7912 NaN 01-Jan-2004 4.8192 NaN 01-Jan-2005 4.627 NaN 01-Jan-2006 4.3875 NaN 01-Jan-2007 4.4748 NaN 01-Jan-2008 4.7219 NaN 01-Jan-2009 2.9052 NaN 01-Jan-2010 2.6398 NaN 01-Jan-2011 4.9234 NaN 01-Jan-2012 3.3216 NaN
  5 Comments
Adam Danz
Adam Danz on 17 Dec 2021
> When I use T.FDD it does not work, since I get the error: All input arguments must be tables.
My bad. What I meant to suggest is instead of using numeric column indexing, use the name of the column if the name is known in advanced. For example, instead of T(:,8), use T(:,'FDD') where FDD is column 8. Table indexing using variable names is safer because the order of columns can change in a table.
Regarding your second question, it sounds like you just need to used indexing. Use month to return the month number for each datetime value and then use ismember to determine which elements of the datetime vector are within your list of months.
Example:
dtm = datetime(1999,01,01) + days(1:15:1000)'
desiredMonths = [7 8 9];
isDesiredMonth = ismember(month(dtm), desiredMonths)
Now you can use the logical vector isDeisredMonth to isolate rows of your table that are within your list of desired months.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!