Determine daily derivative of time series data

7 visualizaciones (últimos 30 días)
I have a timeseries of oxygen (DO) data collected at 5 minute intervals. I want to calculate the daily derivate of oxygen (so 288 data points in each derivative). I know how to calculate the derivative over time dDO/dt but I'm not sure how to use the diff function (is that what I should be using) to calculate a daily value instead of the derivative over each 5-minute interval. I'm sorry if this is a dumb question. My ultimate goal is to plot the daily derivative of oxgyen (DO) against irradiance data to see if light drives the amount of oxygen produced.
I have attached a mat file of time (MX), oxygen (DO) and light (irradiance)
  2 comentarios
Stephan
Stephan el 6 de Oct. de 2019
There is a problem in your data:
>> load('do_deriv.mat')
>> sum(isnan(DO))
ans =
30342
DO contains many NaN values.
Heidi Hirsh
Heidi Hirsh el 6 de Oct. de 2019
Good catch! It's because I saved oxygen on the same timestamps as a longer timeseries but I only have 2 weeks of oxygen data...

Iniciar sesión para comentar.

Respuesta aceptada

Thiago Henrique Gomes Lobato
Thiago Henrique Gomes Lobato el 6 de Oct. de 2019
Editada: Thiago Henrique Gomes Lobato el 6 de Oct. de 2019
For you to calculate the daily derivative you have to define a daily measurement for your variables. Normally the average is a good choice, you can then group the mean of each 288 values in a vector and only then use diff, otherwise you will have the derivative of every 5 minutes. As Stephan said, you have indeed many NaN values in your data, this may be a problem if you want to have the results for all days, but since there are still some valid data points, I wrote a code that takes the NaN in consideration.
% Load Data
Data = load('do_deriv.mat');
% Block Data in 288 Element buffers
DoDailyBuffers = buffer(Data.DO,288);
IrradianceDailyBuffers = buffer(Data.irradiance,288);
% Get the mean value of each buffer to become a daily average
DoDaily = nanmean(DoDailyBuffers); %nanmean to ignore any NaN values
IrradianceDaily = nanmean(IrradianceDailyBuffers);
DoDt = diff(DoDaily); % Derivative with respect to days
figure,
subplot(1,2,1)
plot(IrradianceDaily(2:end),DoDt,'*','linewidth',3)
grid on, set(gca,'fontsize',18)
xlabel('Irradiance (Daily Average)')
ylabel('Daily derivative of oxgyen')
subplot(1,2,2)
plot(IrradianceDaily,DoDaily,'*','linewidth',3)
grid on, set(gca,'fontsize',18)
xlabel('Irradiance (Daily Average)')
ylabel('Oxygen (Daily Average)')
The left graphic is what you asked, but in my opinion, to see if light drives the amount of oxygen, the right one could give you a better insight. There you direct see the relation between both variables which, in this case, looks somewhat linear. You can then verify the correlation coefficient between the data:
NotNaNIndex = ~isnan(DoDaily);
R = corrcoef(DoDaily(NotNaNIndex),IrradianceDaily(NotNaNIndex))
R =
1.0000 0.8462
0.8462 1.0000
0.8462 is a relatively high correlation coefficient, which could imply that oxygen increases with Irradiance.
  3 comentarios
Heidi Hirsh
Heidi Hirsh el 6 de Oct. de 2019
@Thiago I can't figure out where that lowest irradiance mean is coming from. Why doesn't it show up in the derivative plot?
Thiago Henrique Gomes Lobato
Thiago Henrique Gomes Lobato el 6 de Oct. de 2019
Editada: Thiago Henrique Gomes Lobato el 6 de Oct. de 2019
Sorry, I didn't make the check before because I considered that each day had the exact same number of points. In the buffer function the last buffer has only NaN and then is zero filled in order to the buffer dimensions be consistent, so you get, for the last point of DoDaily a mean of zeros that is, of course, zero. This doesn't appear by the derivation because the before last point is a NaN. A quick fix for it is just to shorter the result array after the buffer by one.
DoDaily = nanmean(DoDailyBuffers); %nanmean to ignore any NaN values
IrradianceDaily = nanmean(IrradianceDailyBuffers);
% Remove additional day created by the buffer
DoDaily = DoDaily(1:end-1);
IrradianceDaily = IrradianceDaily(1:end-1);
Your correlation index also increases in the end:
NotNaNIndex = ~isnan(DoDaily);
R = corrcoef(DoDaily(NotNaNIndex),IrradianceDaily(NotNaNIndex))
R =
1.0000 0.8866
0.8866 1.0000

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Smoothing en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by