How to make a linear regression from an excel file
Show older comments
Hi all,
This question is related to mechanics of materials if anyone can help. I have an excel file (a large one, 102k rows) with three columns: cycle count, force and strain.
Data was taken at a frequency of 8Hz (8 datapoints/sec, each cycle count lasts for about 40 rows) and I need to write a code to find the two points in each cycle (one in the increasing portion of the cycle, the other in the decreasing portion) where the correlation between strain and force becomes no longer linear (i.e. R^2 less than 95%), that is the elastic limit of the material. Basically the output would be a matrix with a number of rows equal to the number of cycles and three columns: cycle count, max elastic limit, min elastic limit.
Thank you for anything!
4 Comments
Rik
on 15 Mar 2021
The first step would be to load your data to Matlab. Then you will need to separate the cycles. Only then you can start fitting a linear function on parts of your data. Which step is causing you problems? Note that attaching example data might help in solving your issue.
Nick Elias
on 15 Mar 2021
Rik
on 15 Mar 2021
OK, so which part of the coding is causing you trouble? From what I understand you want to do an analysis on the parts of your data separatly for every value of cycle. How did you try to separate the several chunks?
Nick Elias
on 15 Mar 2021
Answers (1)
You can use the unique function and a loop.
(edited to include a custom function to extract a specific strain value)
data=xlsread('Sample Data.xlsx');
count=data(:,1);
strain=data(:,2);
force=data(:,3);
unique_counts=unique(count);
elasticlimit=zeros(size(unique_counts));
meanstrain=zeros(size(unique_counts));
for n=1:numel(unique_counts)
c=unique_counts(n);
rows=ismember(count,c);
strain_=strain(rows);
force_=force(rows);
%now you have the strain and the force for a specific cycle
%here you can do the processing you need
elasticlimit(n)=find_elasticlimit(force_,strain_);
%you can also use simple functions here, like mean():
meanstrain(n)=mean(strain_);
end
disp(elasticlimit.')
function elasticlimit=find_elasticlimit(force,strain,thres)
%Write an explanation for what this function does here.
if nargin<3,thres=0.99;end%set default
found=false;
for N=2:numel(strain)
R=corrcoef(strain(1:N),force(1:N));
R=R(2);
if R<thres,found=true;break,end
end
if found
elasticlimit=strain(N-1);
else
%return an error condition or error
%you should decide what is appropriate
elasticlimit=NaN;
end
end
27 Comments
Nick Elias
on 16 Mar 2021
Rik
on 16 Mar 2021
I showed you how to do something with the force and the strain for each unique cycle count. How can you modify my code to reach the result you need? Your comment sounds like you just need to use min and max instead of mean.
Nick Elias
on 16 Mar 2021
You can use my answer to split the cycles. That is the first step. Now you continue to the next step. 1 Google search taught me how to calculate the correlation coefficient with Matlab:
N=16;
R=corrcoef(strain_(1:N),force_(1:N));
R=R(2);
fprintf('R=%.6f\nstrain=%.6f\n',R,strain_(N))
So now you have to figure out how you can determine the value of N where the next value of R will drop below 0.99. That should not be too hard by now (hint: don't calculate what the next R will be, just calculate R and subtract 1 from N if you drop below 0.99, and be careful to not make N larger than the number of elements in strain_ and force_).
Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
I didn't pick N, you did. You can use a loop that increments N until you reach your required condition.
I will write something once I'm back at computer.
Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
In the meantime you can try if you can use a loop to find a solution yourself.
Nick Elias
on 17 Mar 2021
Your instinct is correct: your code is doing too many things. You can split the work by creating a new function:
data=xlsread('Sample Data[1].xlsx');
count=data(:,1);
strain=data(:,2);
force=data(:,3);
unique_counts=unique(count);
elasticlimit=zeros(size(unique_counts));
for n=1:numel(unique_counts)
c=unique_counts(n);
rows=ismember(count,c);
strain_=strain(rows);
force_=force(rows);
%now you have the strain and the force for a specific cycle
%here you can do the processing you need
elasticlimit(n)=find_elasticlimit(force_,strain_);
end
disp(elasticlimit.')
function elasticlimit=find_elasticlimit(force,strain,thres)
%Write an explanation for what this function does here.
if nargin<3,thres=0.99;end%set default
found=false;
for N=2:numel(strain)
R=corrcoef(strain(1:N),force(1:N));
R=R(2);
if R<thres,found=true;break,end
end
if found
elasticlimit=strain(N-1);
else
%return an error condition or error
%you should decide what is appropriate
elasticlimit=NaN;
end
end
Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
I don't get only zeros. Did you run the exact code I posted?
I do get many NaN as a result, which signals that in many cases the correlation doesn't drop below 0.99.
Nick Elias
on 17 Mar 2021
Edited: Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
Yes, you will need to put the function in a separate file, or make your script a function.
Putting a function inside a script file is only a valid syntax since R2016b.
Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
You're welcome.
I will edit my answer to include the function.
If you feel my answer solved your issue, please consider marking it as accepted answer. Otherwise, feel free to post a comment with your remaining issues.
Nick Elias
on 17 Mar 2021
Edited: Nick Elias
on 17 Mar 2021
Rik
on 17 Mar 2021
Why? Doesn't the current form of the answer make more sense? You can easily put it in your code if you need it.
Nick Elias
on 17 Mar 2021
Nick Elias
on 19 Mar 2021
Rik
on 19 Mar 2021
I don't fully understand what you mean, but it sounds like you want the second output of max and min. If you want the max force over your entire dataset, why would you use force_?
Nick Elias
on 19 Mar 2021
Rik
on 19 Mar 2021
That does indeed sound like you need the second output of max and min. Did you read the documentation and try to understand the examples?
Nick Elias
on 19 Mar 2021
Rik
on 19 Mar 2021
Both the min and max functions have a second output parameter. What does it do? It gives you the position in the vector where this minimum/maximum value was found. You need to use that to extract the corresponding value from the other array.
I don't know if Onramp will teach you this specific thing, but it seems like you could use a good tutorial. You might also try to find someone physically near you who can guide you in an interactive manner.
Nick Elias
on 23 Mar 2021
Unaccepting my answer comes across as a bit childish.
You need to use the second output of min. That second output contains indices. You can use those indices on the original vector you use in min, or for another vector.
v1=[9 0 6];
v2=[2 4 6];
[val,ind]=min(v1)
v2(ind)
Categories
Find more on Mathematics 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!