replace values in char array if conditions are met

I have a datestr of 15 minute data from a certain location (minDNB):
ex) minDNB = '00','15','30','45','00','15',30','45' etc.
my goal is to replace each value or create a new matrix with fractions of an hour:
goal: newminDNB = 0.00, 0.25, 0.50, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00, etc.
How should I go about this? I would like to loop through minDNB because some time stamps are missing and I need to retain gaps in the data. Thanks.
time00 = '00';
time25 = '15';
time50 = '30';
time75 = '45';
A = size(minDNB)
for i = 1:numel(minDNB)
if minDNB(i) == time00
A(i) = 0.00;
else if minDNB == time25
A(i) = 0.25 ;
else if minDNB(i) == time50
A(i) = 0.50 ;
else if minDNB(i) == time75
A(i) = 0.75 ;
end
end
end
end
end

 Accepted Answer

I think your input is a cell array of character vectors:
minDNB={'00','15','30','45','00','15', '30','45'}
minDNB = 1×8 cell array
{'00'} {'15'} {'30'} {'45'} {'00'} {'15'} {'30'} {'45'}
and you want the output to be doubles, could you just do:
str2double(minDNB)/60
ans = 1×8
0 0.2500 0.5000 0.7500 0 0.2500 0.5000 0.7500
Or a fun alternative:
hours(minutes(str2double(minDNB)))
ans = 1×8
0 0.2500 0.5000 0.7500 0 0.2500 0.5000 0.7500

4 Comments

Thanks Dave! I went down this path too. My only concern here is how do I retain the hours?
I need my ans = 0 0.2500 0.5000 0.7500 1.00 1.2500 1.5000 etc.
And I cannot just create an array spaced out by .2500 because there are a few missing data points that I need to keep track of.
I don't know what you mean by retain the hours, can you elaborate? Is it that you have 1:15 and you want that to convert to 1.25? or maybe you can post a little mat file with some examples of the input data and what you expect for output?
See attached. S is the structure with all station data. totalDNB is the full time stamp. minDNB and hourDNB are minute and hour seperated from the total date string.
The original data is in 15 minute intervals. My output needs to be in fractions of an hour. ( minute 15 -> minute 0.25)
My main point of confusion is how do I loop through the file the get 1) each fifteen minute interval converted to fractions of an hour and 2) how can I also keep the hour.
My desired output is a variable with size(minDNM). and somehow include the hours with minutes. (0.00 00.25 00.50 0.75 01.25 01.50 01.75 02.00...23.75 = 1 days worth of data. Let me know if I can explain further.
This is pretty similar to @Stephen's answer below but with a modification because your data are one big char and not a cell array of chars. I used double(string( for this but you could allso use str2double(cellstr(. And also I changed the < to a <= note this caveat:
if you're missing 1 or 2 consecutive measurements it's fine, if you want to increment the hour when you're missing 3 measurements (i.e. '00' '15' '30' '30' '45') then < should be <=, and if you're missing 4 measurements it's of course indistinguishable from just being the next hour!
mins=double(string(minDNB));
hrs = mins/60;
hrs=cumsum([0;diff(hrs)<0])+hrs;
But note: if you started with timeDNB, there's a way more natural path:
dt=datetime(timeDNB); % convert to datetime
hrs2=hours(dt-dt(1)); % or alternatively: [0;cumsum(hours(diff(dt)))]
This catches that you're missing measurements on March 11th (I think?)

Sign in to comment.

More Answers (1)

C = {'00','15','30','45','00','15','30','45'};
V = str2double(C)/60;
V = V+cumsum([0,diff(V)<0])
V = 1×8
0 0.2500 0.5000 0.7500 1.0000 1.2500 1.5000 1.7500

3 Comments

Given your uploaded data you should just use DURATION objects:
unzip('Riverstn.mat.zip')
S = load('Riverstn.mat')
S = struct with fields:
S: [7×1 struct] hourDNB: [103694×2 char] minDNB: [103694×2 char] timeDNB: {103694×1 cell}
H = str2double(cellstr(S.hourDNB));
M = str2double(cellstr(S.minDNB));
D = duration(H,M,zeros(numel(M),1))
D = 103694×1 duration array
00:00:00 00:15:00 00:30:00 00:45:00 01:00:00 01:15:00 01:30:00 01:45:00 02:00:00 02:15:00 02:30:00 02:45:00 03:00:00 03:15:00 03:30:00 03:45:00 04:00:00 04:15:00 04:30:00 04:45:00 05:00:00 05:15:00 05:30:00 05:45:00 06:00:00 06:15:00 06:30:00 06:45:00 07:00:00 07:15:00
Thanks everyone! Ended kind of combining everyones suggestions.
minDNB_fmt = datetime(dateDNB,'Format','mm');
hourDNB_fmt = datetime(dateDNB,'Format','HH');
minDNB = str2double(cellstr(minDNB_fmt));
hourDNB = str2double(cellstr(hourDNB_fmt));
duration_DNB = duration(hourDNB,minDNB,zeros(numel(minDNB),1));
[hh,mm] = hms(duration_DNB);
minutes_DNB = mm /60;
hourmin_DNB = horzcat(hh+minutes_DNB);
if you're just going through cellstrs to get from datetime to double, you can skip that step:
d=datetime(2010,1,1,10,30,00);
d.Hour
ans = 10
d.Minute
ans = 30

Sign in to comment.

Categories

Asked:

on 3 Nov 2021

Commented:

on 4 Nov 2021

Community Treasure Hunt

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

Start Hunting!