Create subsets of data within a timetable

I have a timetable (TT) and I need to create data subsets based on time duration vectors. The code below does what I need but I ended up with 6 timetables in my workspace, which is a problem for me because I then need to do a for loop to conduct several operations on each subset and I don't know how to iterate through different timetables. I would be so grateful if someone could tell me if there is a way to have these 6 subsets all in a single timetable so I can then have a loop iterating through them? Alternatively, how can I loop through my different timetables, considering they have different names (t1, t2, etc)? Thank you so much in advance for your help!
t1 = TT(timerange(hours(00), hours(04)), :);
t2 = TT(timerange(hours(04), hours(08)), :);
t3 = TT(timerange(hours(08), hours(12)), :);
t4 = TT(timerange(hours(12), hours(16)), :);
t5 = TT(timerange(hours(16), hours(20)), :);
t6 = TT(timerange(hours(20), hours(24)), :);

 Respuesta aceptada

Guillaume
Guillaume el 8 de Feb. de 2017
Editada: Guillaume el 9 de Feb. de 2017
As you've discovered creating six individually named timetables is not a good idea. As a rule, as soon as you start numbering variables, you're doing something wrong.
starttimes = 0:4:20;
endtimes = 4:4:24;
tts = arrayfun(@(s, e) TT(timerange(hours(s), hours(e)), :), starttimes, endtimes, 'UniformOutput', false);
will create a cell array with your 6 timetables. It's then trivial to iterate over the element of the cell array:
for tidx = 1:numel(tts)
tts{idx}
%do something with tts{tidx}, a single timetable
end
Alternatively, instead of looping over the timetables in the cell array, you could indeed just merge them into one by concatenating them vertically:
filteredtt = vertcat(tts{:})

4 comentarios

Thank you very much for helping me! I am having problems running the line below: "Undefined function or variable 'timerange'" is the error. I am trying to understand the arrayfun in the documentation but I find it very hard (sorry I am a beginner!). Could you please tell me what is (s, e). Shouldn't this be defined before?
tts = arrayfun(@(s, e) TT(timerange(hours(s), hours(e), :), s, e, 'UniformOutput', false);
I made a typo in my original answer (missing closing parenthesis) which was most likely the cause for the error.
arrayfun is an easy way to write a loop that iterates over the elements of a matrix/matrices. The above arrayfun is exactly equivalent to:
assert(isequal(size(starttimes), size(endtimes)); %arrayfun checks that the inputs have he same size
tts = cell(size(starttimes)); %because of 'UniformOutput', false, arrayfun creates a cell array
for idx = 1:numel(starttimes) %loop over all the elements
s = starttimes(idx);
e = endtimes(idx);
tts{idx} = TT(timerange(hours(s), hours(e)), :);
end
arrayfun is often used in conjunction with anonymous functions. Above, the
@(s, e) TT(timerange(hours(s), hours(e)), :)
is an anonymous function. This is more or less equivalent to creating a function in a separate file with the code:
function output = somename(s, e)
output = TT(timerange(hours(s), hours(e)), :);
end
Except the above function wouldn't know what TT is whereas an anonymous function can see all the variables in the enclosing function.
Hope it's a bit clearer. I like arrayfun as it is a great way to say: transform this sequence(s) of values into another sequence, using this function.
Thank you so much! Breaking down the arrayfun was extremely helpful! I understand now. There is only one last question. If I understood correctly, the arrayfun should replace the loop. However, there might be something missing to the line below because I still get an error (after fixing the missing closing parenthesis): "Undefined function or variable 's'".
tts = arrayfun(@(s, e) TT(timerange(hours(s), hours(e)), :), s, e, 'UniformOutput', false);
Is this because in the below I did not define s and e? I played with it and tried the below, which worked. Is this the correct way? Thank you so much, Guillaume!
starttimes = 0:4:20;
endtimes = 4:4:24;
tts = arrayfun(@(starttimes, endtimes) TT(timerange(hours(starttimes), hours(endtimes)), :), starttimes, endtimes, 'UniformOutput', false);
Yes, sorry another typo. It should have been
tts = arrayfun(@(s, e) TT(timerange(hours(s), hours(e)), :), starttimes, endtimes, 'UniformOutput', false);
The s and e in @(s, e) TT(timerange(hours(s), hours(e)), :) are the input variables to the anonymous function. They can be any name you want (as long as you use the same names in the body of the anonymous function: TT(timerange(hours(s), hours(e)), :)).
s and e take in turn all the values in the input arrays to arrayfun and these should of course be variables that exist, that is your original starttimes and endtimes.

Iniciar sesión para comentar.

Más respuestas (1)

Peter Perkins
Peter Perkins el 8 de Feb. de 2017
Another possibility is to keep the one timetable, but add a grouping variable to indicate which segment a given row is in. Then use either varfun or rowfun, specifying that grouping variable to work on each segment separately. Not sure what you're doing with each segment, so it's hard to give specific advice, but the first step probably looks something like
tt.Segment = discretize(tt.Time,hours(0:4:24),'categorical')

Categorías

Más información sobre Loops and Conditional Statements en Centro de ayuda y File Exchange.

Etiquetas

Preguntada:

el 8 de Feb. de 2017

Comentada:

el 9 de Feb. de 2017

Community Treasure Hunt

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

Start Hunting!

Translated by