# plot data differences

I have the following data:

data12 = {
{1, 981.946, 978.783, 978.783},
{2, 813.948, 810.783, 810.667},
{3, 743.422, 743.447, 744.062},
{4, 715.382, 715.478, 715.326},
{5, 690.345, 696.075, 691.664},
{6, 862.126, 870.902, 860.371}
};


I want to make a ListLinePlot using the first row element (the index) as the X coordinate, and for the Y coordinate, the difference between the second and third value in row (generally speaking, the difference between two generic columns). How can I do it?

=== EDIT ===

I've found this solution:

ListLinePlot[{#[[1]], #[[2]] - #[[3]]} & /@ data12]


Is it a good solution, or is there a better way to accomplish this?

-
Thus, you want to completely ignore the fourth and last column? –  Mark McClure Oct 2 '12 at 14:35
No, I want to choose columns, but I've asked a simpler question because then I want to generalize it by myself. –  Jepessen Oct 2 '12 at 14:37

I'm just going to map the pure function {#[[1]],#[[3]]-#[[2]]}& onto the data before calling ListLinePlot.

data12 = {
{1, 981.946, 978.783, 978.783},
{2, 813.948, 810.783, 810.667},
{3, 743.422, 743.447, 744.062},
{4, 715.382, 715.478, 715.326},
{5, 690.345, 696.075, 691.664},
{6, 862.126, 870.902, 860.371}
};
ListLinePlot[{#[[1]],#[[3]]-#[[2]]}& /@ data12]

-
I've found the same solution... Nice... –  Jepessen Oct 2 '12 at 14:39

Another way can be operating on the column vectors. Transpose gives columns then we use the pure function for the subtraction and a second Transpose brings the result into a form required by ListLinePlot. Notice that the column numbers of data12 are reflected similarly in the Slot sequence numbering.

ListLinePlot[Transpose@({#1, #3 - #2} & @@ Transpose[data12])]


BR

-
Too complicated. Try ListLinePlot[{#1, #3 - #2} & @@@ data12]. –  Ｊ. Ｍ. Oct 2 '12 at 14:56
Thanks that's a nice solution –  Jepessen Oct 2 '12 at 14:57
@J.M. Thx! An eyeopener indeed.. –  PlatoManiac Oct 2 '12 at 14:59

Your method can be made more concise by using Slot (#, #2, etc.) and Apply at level 1 (@@@):

ListLinePlot[{#, #2 - #3} & @@@ data12]


I see this was recommended by J.M. in an earlier comment.

This is also faster than your method:

dat = RandomChoice[data12, 500000];

{#[[1]], #[[2]] - #[[3]]} & /@ dat // Timing // First

{#1, #2 - #3} & @@@ dat // Timing // First


0.53

0.328

The method recommended by PlatoManiac is much faster still:

Transpose[{#1, #3 - #2} & @@ Transpose[dat]] // Timing // First


0.078

Equally fast in another method using Part:

Transpose[{#[[All, 1]], #[[All, 2]] - #[[All, 3]]} &@dat] // Timing // First


0.078

-

While not a faster solution, you can also try using a replacement rule (which can sometimes lead to more "readable" code):

ListLinePlot[data12 /. {c1_, c2_, c3_, c4_} -> {c1, c3 - c2}]

-