Extract row from table immediately before/after specified range

35 views (last 30 days)
Hello,
I am currently trying to code for preferential behavior for phototaxis in fly models. My idea is to focus on the "transition" between light and dark and the time spent there.
I am trying to extract data from a table that is immediately before and after a specified range to sort. In essence, I specify a filter for certain values where (x>y) in a predefined table. Could I grab the value immediately before first instance of that, and the one after?
So in table
1 2 3 4
5 6 7 8
9 10 11 12
13……….16
I grab data in cells 5-8 but is there a way to then also grab 9-12 and 1-4?
Currently, code below takes all instances where my yroi is greater or less than roicenter, plotting in different colors. However, I am more interested on the "transition period" which includes the data immediately before and immediately after that filter. So I am looking for a way to get the row of data immediately before and after y_roi > or < roicenter, so I can then find the difference between the two for all instances in my loop, before plotting it. So if fly wtransitions dark->light @ frame 200, but goes light->dark at frame 250, I am interested in the difference 250-200
End goal is to then plot this "preference score" in stacked bars as a percentage of total time.
Thanks in advance for the help.
%Calculate the center of each ROI
roicenter = expmt.meta.roi.centers(:,2);
%Set the days to analyze
start_time = seven_am_idx;
final_time = seven_am_idx + (259022);
%Extract Y values from Margo for ROI and setting comparisons
y_roi = squeeze(centroids(:,2,:));
asabove = (y_roi > roicenter');
sobelow = (y_roi < roicenter');
%Set up ROIs of interest
start_ROI = 1;
stop_ROI = 1;
bin = 240;
%--------------------------------------------------------------------------
%Set up a quick comparison to determine Preference Score for above the
%center
for j = (start_ROI:stop_ROI)
dummyabove = [];
dummybelow = [];
for i = (start_time:bin:final_time)
%all nonzero insances
abovetest = nonzeros(asabove(i:(i+bin),j));
abovetest = abovetest(~isnan(abovetest));
dummyabove(length(dummyabove)+1) = sum(abovetest);
%Set up a quick comparison to determine Preference Score for Below the
%center
belowtest = nonzeros(sobelow(i:(i+bin),j));
belowtest = belowtest(~isnan(belowtest));
dummybelow(length(dummybelow)+1) = sum(belowtest);
end
end

Accepted Answer

Isaac Rose
Isaac Rose on 14 Nov 2022
My understanding is that the main challenge is retrieving the indices of the values in the table where y_roi is greater or less than roicenter. With this information, you could then index into the regions of the table just before and after this set of indices. You can do this using the ‘find’ function, documented here:
For example, in the sample table you shared with values 1-16 (let’s call it “A”), you can capture the rows above and below the row containing 5-8 as follows:
% Create array
A = reshape(1:16,4,4)';
% Find target row indices
[row,col] = find(A >= 5 & A <= 8);
% Get values of surrounding rows
rowAbove = A(min(row)-1,:)
rowAbove = 1×4
1 2 3 4
rowBelow = A(max(row)+1,:)
rowBelow = 1×4
9 10 11 12
Alternatively, you can also take a set number of values before and after this range using the following steps:
1. Take the transpose of the matrix so that the sorted values are column-major (increment down columns first):
B = A';
This is because MATLAB indexes matrix entries in column-major order, so working with a sorted column-major matrix will be more intuitive.
2. Retrieve the indices for the values between 5 and 8 with the following command:
idx = find(B >= 5 & B <= 8);
3. You can then capture the 4 values before and 4 values after this range:
first = idx(1);
last = idx(end);
fourAbove = B(first-4:first-1)
fourAbove = 1×4
1 2 3 4
fourBelow = B(last+1:last+4)
fourBelow = 1×4
9 10 11 12
Just be sure that you avoid any array index-out-of-bounds errors in your implementation.
The above implementation assumes that the values are stored in an array. If they are actually stored in a Table object, then some of the syntax would be different. For example, you would instead need to execute:
[row,col] = find(A{:,:} >= 5 & A{:,:} <= 8);
and use curly braces when indexing into the table to retrieve values.

More Answers (0)

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!