3
$\begingroup$

This may seem silly, but I've been crazy for the last hour trying to find a way to automate the linear fit of my data. All I need is the slope.

Say I have some data list={1,2,3,4,5,6,7,8}; and want to find the slope that fits it best, something like m = Slope[list], so that I can use m wherever I want.

Fit[{1, 2, 3, 4, 5, 6, 7}, {1, x}, x] returns me 4.0284*10^-15 + 1. x, in wich case the value I want is 1.. How can I get that value programmaticly? The function Fit returns the results in a not very useful form... Why?

Notice that I have 2337 curves to fit. I can't do them all by eye or copy and paste. Surely I'm missing something.

Thanks

$\endgroup$
  • 1
    $\begingroup$ D[Fit[{1, 2, 3, 4, 5, 6, 7}, {1, x}, x], x]? $\endgroup$ – Michael E2 Jun 28 '16 at 15:35
  • 1
    $\begingroup$ Coefficient[Fit[{1, 2, 3, 4, 5, 6, 7}, {1, x}, x], x] works too. $\endgroup$ – J. M. is away Jun 28 '16 at 15:42
  • 6
    $\begingroup$ Or if you want a sophisticated way, lm = LinearModelFit[{1, 2, 3, 4, 5, 6, 7}, {1, x}, x]; First@Pick[lm["BestFitParameters"], lm["BasisFunctions"], x]. There are lots of fitting functions. Try ?*Fit. $\endgroup$ – Michael E2 Jun 28 '16 at 15:43
  • 1
    $\begingroup$ @J.M. Better than D, esp. when the model has other functions. $\endgroup$ – Michael E2 Jun 28 '16 at 15:44
  • $\begingroup$ if you've given your LinearModelFit a variable name like lm then Coefficient[ lm[x], x ] will work. $\endgroup$ – Joe Feb 5 '18 at 6:21
4
$\begingroup$

Putting my comment into a function:

bestFitSlope[data_] := Module[{lm, x},
   lm = LinearModelFit[data, {1, x}, x]; 
   First@Pick[lm["BestFitParameters"], lm["BasisFunctions"], x]
   ];

Example. Suppose you have a list of datasets, then you can Map (/@) the function bestFitSlope over the list.

SeedRandom[0, Method -> "MersenneTwister"];
n = 6;                        (* number of datasets to make uo *)
slopes = RandomReal[5, n];    (* slopes of the lines *)
datasets = Table[
   20 i + slopes[[i]] x + RandomReal[{-2, 2}], (* line + noise *)
   {i, n}, {x, 15}];

ListPlot@datasets

Mathematica graphics

The we can get the slopes of the fitted lines and compare them with the "theoretical" slopes:

bestFitSlope /@ datasets
slopes
(*
{2.12046, 2.90695, 0.189475, 3.72127, 0.314697, 4.21059}
{2.1471, 2.90036, 0.151295, 3.81398, 0.253895, 4.23242}
*)

Note: The function bestFitSlope throws away the linear model it constructs. You might want to keep it for the other information it contains (see LinearModelFit).

$\endgroup$
  • $\begingroup$ Yes. The solution does seem to be to define the Slope[list_]:=... function. I just wasn't used to manipulating data if not in lists or value output. $\endgroup$ – A. Vieira Jun 29 '16 at 21:06
2
$\begingroup$
list = {1, 2, 3, 4, 5, 6, 7, 8};

Plot your list:

ListPlot[list, Joined -> True, PlotMarkers -> {Automatic}, 
Frame -> True, GridLines -> Automatic]

enter image description here

And since you asking: something like m = Slope[list], so that I can use m wherever I want. You certainly remember the concept of slope

enter image description here

And you should read Defining Functions, How to | Create Definitions for Variables and Functions, Setting Up Functions with Optional Arguments, Functions as Procedures and Defining Variables and Functions

So can do:

m[x1_, x2_, y1_, y2_] := (y2 - y1)/(x2 - x1)

m[2, 4, 2, 4]

1

$\endgroup$
1
$\begingroup$

Here's a simple way.

lineData = Fit[list, {1, x}, x];
val  = Last[lineData];
val /. x -> 1

This will give you the value of the slope of the linear fit.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.