how to delete nan values from array columns without losing data from other columns
    2 views (last 30 days)
  
       Show older comments
    


i have a huge file from a lab expremient 
every run gives me 4 columns and every 2 out of the 4 start with nan then 2 nan vars and end with nan and 3 nan vars i want to delet the nan values without losing any data so that when i try to make graphs from it every graph will have enough inputs  and neither of them get lost 
 i am espisally troubled by the second 2 columns of every 4 and how to deal with them
11 Comments
  Mathieu NOE
      
 on 14 May 2024
				glad I could help a bit , but this was just a starter 
ok, let's focus on the selected runs (for both files I presume ?)
these 2 lines are indeed just to extract a block of 4 contiguous columns , and we simply shift by a factor 4 when we change to the next run : 
    ind_cols = (1:4)+(ck-1)*4;
    data_this_run = data(:,ind_cols);
and yes this line is not anymore of any use (I used it for another purpose that I removed afterwards) :     [m,n] = size(data_this_run);
I'll come back soon with a new code 
Accepted Answer
  Mathieu NOE
      
 on 14 May 2024
        ok, so this is now the main dishes.... 
have first tried this code on the first data file , will adapt to your new files as soon as possible 
have fun ! 
data= readmatrix('expr2lab.csv'); % or  readtable or whatever
runs = [12 , 16 ,17,20,22,24,29,30,31,34,33,11]; % selection of best runs
%% main loop
for ck = 1:numel(runs)
    k = runs(ck);
    ind_cols = (1:4)+(k-1)*4; % Time (s) 	Position (m) 	Velocity (m/s) 	Acceleration (m/s²) 
    data_this_run = data(:,ind_cols);
    [m,n] = size(data_this_run);
    Time = data_this_run(:,1);
    Position = data_this_run(:,2);
    Velocity = data_this_run(:,3);
    Acceleration = data_this_run(:,4);
    %% fit on acceleration data 
    % remove all NaN's first
    ind = isnan(Time) | isnan(Acceleration);
    Time(ind) = [];
    Position(ind) = [];
    Velocity(ind) = [];
    Acceleration(ind) = [];
    % select valid data between first max peak and end of data 
    [v,indm] = max(Acceleration); % search for the first positive max peak
    nn = numel(Time);
    [b,yf] = exp_decay_sinus_fit(Time(indm:nn),Acceleration(indm:nn));
    % b array contains 5 coefficients according to this equation (model)
    % y = b(1).*exp(b(2).*x).*(sin(2*pi*b(3)*x + b(4))) + b(5)
    eq_str = [ ' y =  ' num2str(b(1),'%.2f'),'* exp(-' num2str(-b(2),'%.2f') ' t * sin(2*pi*' num2str(b(3),'%.2f') ' t + ' num2str(b(4),'%.2f') ' ) + (' num2str(b(5),'%.2f') ')'];
    figure(ck)
    subplot(3,1,1),plot(Time,Position)
    title(['Run # : ' num2str(k)]);
    ylabel('Position');
    subplot(3,1,2),plot(Time,Velocity)
    ylabel('Velocity');
    subplot(3,1,3),plot(Time,Acceleration,Time(indm:nn),yf);
    ylabel('Acceleration');
    legend('data',eq_str);
end
%%%%%%%%%%%%%%% functions %%%%%%%%%%%%%%%%%%%%%%
function [B,yf] = exp_decay_sinus_fit(t,y)
    [yu,indm] = max(y);
    yl = min(y);
    yr = (yu-yl);                                                                   % Range of y
    yz = y-yu+(yr/2);
    % zero crossing are performed on first 1/3 of data (better signal to
    % noise ratio)
    n = round(numel(y)/3);
    yz = yz(indm:n); % extract from first major peak to end of 30% of data
    zt = t(yz(:) .* circshift(yz(:),[1 0]) <= 0);                                   % Find zero-crossings
    per = 2*mean(diff(zt));                                                         % Estimate period
    freq = 1/per;                                                                   % Estimate frequency
    % initial phase estimate 
    tmax = t(indm);
    phase_init = mod(-2*pi*freq*tmax + pi/2,2*pi);                                  % initial phase estimate 
    ym = mean(y);                                                                   % Estimate DC value (offset)
    fit = @(b,x)  b(1).*exp(b(2).*x).*(sin(2*pi*b(3)*x + b(4))) + b(5);             % Objective Function to fit
    fcn = @(b) norm(fit(b,t) - y);                                                  % Least-Squares cost function
    B = fminsearch(fcn, [yr; -0.1;  freq;  phase_init;  ym]);                       % Minimise Least-Squares
    if B(4)<0 % complement negative phase with 2pi
        B(4) = B(4) + 2*pi;
    end
    yf = fit(B,t);
end
4 Comments
More Answers (0)
See Also
Categories
				Find more on Data Type Identification 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!



















































