Num of max consective occurance of 'T'
    3 views (last 30 days)
  
       Show older comments
    
Hi,
I have a set of cyclone data that I am trying to analyse. in the sample timetable, each system is described by unique id, for each id i want to count the MAX CONSECTIIVE occuance of 'T' in the 'thrsh' column. I also want to know the closest location of the next or previous 'T' after of before the max conseitive occuance for each system. the final table should be [id, maxOcc, nextLoc]. Some selected ids are shown below:
id = 1990S001, maxOcc = 2, nextT = 0 (no occurance of next or previous T after or before F)
id = 1990S005, maxOcc = 2, nextT = 0
id = 1990S014, maxOcc = 5, nextT = -8 (8th occurance of T before F)
id = 1990S019, maxOcc = 3, nextT = -2 (2nd occurance of T before F)
High appreciate your help.
Thanks
2 Comments
  Ganesh
      
 on 17 Jun 2024
				To clarify, 1990S005 has only 2 entries but you have mentioned that it has a maxOcc of 5. Does this mean that the consecutive Ts should be considered in the system 1990S006 too?
Accepted Answer
  Ganesh
      
 on 17 Jun 2024
        
      Edited: Ganesh
      
 on 17 Jun 2024
  
      You can use the following code:
load('Consective Occ of T.mat')
[uniqueIDs, maxConsecutiveOnes, closestOneIndices] = findMaxConsecutiveOnesAndClosest(barra1.id,cell2mat(barra1.thrsh));
table(uniqueIDs,maxConsecutiveOnes,closestOneIndices)
function [uniqueIDs,maxConsecutiveOnes,closestOneIndices] = findMaxConsecutiveOnesAndClosest(ids, boolChars)
    uniqueIDs = unique(ids); 
    maxConsecutiveOnes = zeros(length(uniqueIDs),1); 
    closestOneIndices = zeros(length(uniqueIDs),1);
    for i = 1:length(uniqueIDs)
        id = uniqueIDs(i);
        boolValues = boolChars(ids == id) == 'T'; % Filters out only values for each ID
        [maxConsecutive, endIndex] = maxConsecutiveOnesHelper(boolValues);
        maxConsecutiveOnes(i) = maxConsecutive;
        if endIndex == 0 %If there are no consecutive 1s, skip
            closestOneIndex = inf;
        else
            closestOneIndex = findClosestOne(boolValues, endIndex, maxConsecutive);
        end
        closestOneIndices(i) = closestOneIndex;
    end
end
function [maxConsec, endIndex] = maxConsecutiveOnesHelper(boolValues)
    maxConsec = 0;
    currentConsec = 0; 
    endIndex = 0;
    % Manually checking the longetst consecutive 1s
    % Can be optimized
    for i = 1:length(boolValues)
        if boolValues(i) == true
            currentConsec = currentConsec + 1;
            if currentConsec > maxConsec
                maxConsec = currentConsec;
                endIndex = i;
            end
        else
            currentConsec = 0;
        end
    end
end
function closestIndex = findClosestOne(boolValues, maxEndIndex, maxConsecutive)
    if maxConsecutive == length(boolValues)
        closestIndex = inf; % I am using inf to denote no close element is present
        return;
    end
    startIndex = maxEndIndex - maxConsecutive + 1;
    % Find the closest distance before the consecutive 1s
    closestBefore = find(boolValues(1:startIndex-1), 1, 'last');
    if ~isempty(closestBefore)
        closestIndexBefore = closestBefore-length(boolValues(1:startIndex-1))-1;
    else
        closestIndexBefore = inf;
    end
    % Find the closest distance after the consective 1s
    closestAfter = find(boolValues(maxEndIndex+1:end), 1, 'first');
    if ~isempty(closestAfter)
        closestIndexAfter = closestAfter;
    else
        closestIndexAfter = inf;
    end
    % Find the minimum
    closestIndex = min(closestIndexBefore,closestIndexAfter);
end
I have implemented a straight forward algorithm, feel free to optimize it!
EDIT: Made a small code fix and added comments for readability!
More Answers (0)
See Also
Categories
				Find more on Logical in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
