# How to subtract two uneven tables

I am looking for a way to plot the difference of two tables, where some elements may be missing in the first or in the second table.

A simple example, given two tables:

A = {{0., 9.84}, {0.5, 9.34}, {1.5, 8.34}, {2., 7.84}, {2.5, 7.34}, {3., 6.84}, {3.5, 6.34}, {4., 5.84}, {4.5, 5.34}, {5., 4.84}};
B = {{0., 10.01}, {0.5, 10.51}, {1., 11.01}, {1.5, 11.51}, {2., 12.01}, {2.5, 12.51}, {3., 13.01},  {4., 14.01}, {4.5, 14.51}, {5., 15.01}};


In the table A the element with the x-value (first elements in the tables) 1 is missing, and in the table B there is no element with x-value 3.5. I need to plot the difference of y-values (second elements in the table) vs x-values. Basically, I need to generate a difference table like this:

{{0., -0.17}, {0.5, -1.17}, {1.5, -3.17}, {2., -4.17}, {2.5, -5.17}, {3., -6.17}, {4., -8.17}, {4.5, -9.17}, {5, -10.17}}


Here is one way:

Cases[GatherBy[Flatten[{A, B}, 1], First], {a_, b_} :> {First@a, a[[2]] - b[[2]]}]
Cases[GatherBy[Flatten[{A, B}, 1], First], {{a1_, b1_}, {a1_, b2_}} :> {a1, b1 - b2}]


Alternatively, first find the x-coordinates they share, use this list to prune A and B, and then do the subtraction:

xs = Intersection[A[[All, 1]], B[[All, 1]]]
prunedLists = Cases[#, {Alternatives @@ xs, _}] & /@ {A, B}
{#1[[1]], #1[[2]] - #2[[2]]} & @@@Transpose@prunedLists
(* {0., 0.5, 1.5, 2., 2.5, 3., 4., 4.5, 5.}
(* {{{0., 9.84}, {0.5, 9.34}, {1.5, 8.34}, {2., 7.84}, {2.5, 7.34}, {3., 6.84}, {4., 5.84}, {4.5, 5.34}, {5., 4.84}},
{{0., 10.01}, {0.5, 10.51}, {1.5, 11.51}, {2., 12.01}, {2.5, 12.51}, {3., 13.01}, {4., 14.01}, {4.5, 14.51}, {5., 15.01}}} *)
(* {{0., -0.17}, {0.5, -1.17}, {1.5, -3.17}, {2., -4.17}, {2.5, -5.17}, {3., -6.17}, {4., -8.17}, {4.5, -9.17}, {5., -10.17}} *)


Not my best, but here's another one-liner:

List @@@ Normal@GroupBy[Join[A, B], First -> Last,
If[Length[#] > 1, Subtract @@ #, Nothing] &] /. {_} :> Nothing


{{0., -0.17}, {0.5, -1.17}, {1.5, -3.17}, {2., -4.17}, {2.5, -5.17}, {3., -6.17}, {4., -8.17}, {4.5, -9.17}, {5., -10.17}}

xlist = Intersection[A[[;; , 1]], B[[;; , 1]]];
Transpose[{xlist, (xlist /.
Thread[A[[;; , 1]] -> A[[;; , 2]]]) - (xlist /.
Thread[B[[;; , 1]] -> B[[;; , 2]]])}]


or equivalently,

Transpose[{xlist, (xlist /. Thread[Rule @@ Transpose@A]) - (xlist /.


I would just interpolate both lists, and then find the difference for each shared x value. The only difference with respect to matheorem's solution is that you can use any x values common to the range of the lists if you need to.

a = {{0., 9.84}, {0.5, 9.34}, {1.5, 8.34}, {2., 7.84}, {2.5,
7.34}, {3., 6.84}, {3.5, 6.34}, {4., 5.84}, {4.5, 5.34}, {5.,
4.84}};
b = {{0., 10.01}, {0.5, 10.51}, {1., 11.01}, {1.5, 11.51}, {2.,
12.01}, {2.5, 12.51}, {3., 13.01}, {4., 14.01}, {4.5, 14.51}, {5.,
15.01}};

{aint,bint} = Interpolation/@{a,b};
commonX = Intersection @@ {a[[All, 1]], b[[All, 1]]};
deltaAB = {#, aint[#] - bint[#]} & /@ commonX


Which gives:

{{0., -0.17}, {0.5, -1.17}, {1.5, -3.17}, {2., -4.17}, {2.5, -5.17}, {3., -6.17}, {4., -8.17}, {4.5, -9.17}, {5., -10.17}}

• Thanks! I also thought about first interpolating the data. But I don't like this method, it may not work properly for the given data, and I really want to substract the elements in the data. – Mikayel Aug 26 '16 at 6:24