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)), :);

 채택된 답변

Guillaume
Guillaume 2017년 2월 8일
편집: Guillaume 2017년 2월 9일

1 개 추천

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

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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Peter Perkins
Peter Perkins 2017년 2월 8일

1 개 추천

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')

카테고리

도움말 센터File Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

태그

질문:

2017년 2월 8일

댓글:

2017년 2월 9일

Community Treasure Hunt

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

Start Hunting!

Translated by