Download as pdf or txt
Download as pdf or txt
You are on page 1of 5

HY013 - Statistics and data analysis methods - HT2023

EXERCISE 6 - ANALYZING LONG-TERM TRENDS IN RIVERINE NUTRIENTS.

Name: Rodney Muganzi

TASK 1: Homogenize Time Series

% Dataset loading. This will be for the Dissolved Nitrogen (DN)


concentrations
data = readtable('/Users/rodneymuganzi/Desktop/Data and Statistics/
HY013_River_nutrient_data.xlsx');

% Creating monthly-averaged time series by grouping the data by year and


% month. Later the mean DN concentrations is calculated.
monthly_avg = groupsummary(data, {'Year', 'Month'}, 'mean', 'DN');

% Plotting the monthly-averaged DN concentrations


figure;
plot(monthly_avg.mean_DN);
title('Monthly-Averaged Time Series of DN Concentrations');
xlabel('Time');
ylabel('Average DN Concentration');

1
% Plotting the Autocorrelation Function (ACF). This is to check for serial
% correlation in the monthly-averaged DN concentrations
figure;
autocorr(monthly_avg.mean_DN);
title('Autocorrelation Function of Monthly-Averaged DN Concentrations');

TASK 2: De-seasonalize Time Series and TASK 3: Mann-Kendall Test for Trend

% Calculating the long-term monthly means. The purpose is to identify


% seasonal patterns in the data
monthly_means = groupsummary(data, 'Month', 'mean', 'DN');

% Calculating lag-one autocorrelation and create adjusted series


monthly_avg = monthly_means.mean_DN; % Extracting the monthly average DN
values

% Calculating lag-one autocorrelation


[acf, lags, bounds] = autocorr(monthly_avg, 'NumLags',1);
lag_one_autocorr = acf(2); % Extracting the lag-one autocorrelation value

% Creating an adjusted series in relation with lag-one autocorrelation


adjusted_series = monthly_avg(2:end) - lag_one_autocorr *
monthly_avg(1:end-1);

% Plot ACF of the adjusted series to check for serial correlation

2
figure;
autocorr(adjusted_series);
title('Autocorrelation of Adjusted DN Concentrations');

%%section break for task 3

% Perform the Mann-Kendall test on the adjusted series. The main purpose
% for this is to detect significant trends as potrayed in appendix B
[S, KendallTau, pValue] = mannKendallTest(adjusted_series);

% Displaying the results


disp(['S statistic: ', num2str(S)]);

S statistic: 13

disp(['Kendall Tau: ', num2str(KendallTau)]);

Kendall Tau: 0.23636

disp(['p-Value: ', num2str(pValue)]);

p-Value: 0.32031

TASK 4: Calculate Trend Magnitude Using Sen's Slope

3
% Calculating Sen's Slope

% The purpose here commence the process to compute Sen's slope as outlined
in Appendix C
n = length(adjusted_series); % Determine the number of data points in the
series
slopes = zeros(n*(n-1)/2, 1); % Initializing an array to store the slopes
k = 1; % An index for storing slopes

% Calculating slopes between all pairs of data points, looping over them
for i = 1:n-1
for j = i+1:n
slopes(k) = (adjusted_series(j) - adjusted_series(i)) / (j - i);
k = k + 1;
end
end

% Determining the Sen's Slope as the median of these slopes


senSlope = median(slopes);

% Converting the slope to the trend per decade


senSlopePerDecade = senSlope * 12 * 10; % There are 12 months in a year and
10 years in a decade

% Compiling the results into a table


resultsTable = table(S, KendallTau, pValue, senSlopePerDecade, ...
'VariableNames', {'S', 'Kendalls_Tau', 'pValue', 'Trend_Per_Decade'});

% Display the table


disp(resultsTable);

S Kendalls_Tau pValue Trend_Per_Decade


__ ____________ _______ ________________

13 0.23636 0.32031 1.3605

% Defining the mannKendallTest function at the end of the script

function [S, KendallTau, pValue] = mannKendallTest(x)


n = length(x);
S = 0;
for i = 1:n-1
for j = i+1:n
S = S + sign(x(j) - x(i));
end
end

4
% Calculate Kendall's tau
KendallTau = S / (n*(n-1)/2);

% Variance and Z-score for S


varS = (n*(n-1)*(2*n+5) - ...
sum(arrayfun(@(i) sum(x==x(i)), 1:n).^3 - ...
sum(arrayfun(@(i) sum(x==x(i)), 1:n)))) / 18;
Z = S / sqrt(varS);

% Two-tailed p-value
pValue = 2 * (1 - normcdf(abs(Z), 0, 1));
end

You might also like