# Subtract lists' elements

I have 2 lists, that have the following form:

List1 = {{0.0, val10}, {0.1, val11}, {0.2, val12},...}
List2 = {{0.0, val20}, {0.1, val21}, {0.2, val22},...}


I would like to make a normalized ListDiff defined in such a way that it has the form:

ListDiff = {{0.0, (val10 - val20)/val10}, {0.1, (val11 - val21)/val11}, {0.2, (val12 - val22)/val12},...}


Is there any procedure in Mathematica to perform this operation?

ListDiff = Transpose[{
List1[[All, 1]],
Subtract[1., List2[[All, 2]]/List1[[All, 2]]]
}]


is slightly faster than Bob Hanlon's second proposal...

Another approach,

List1 = {{0.0, val10}, {0.1, val11}, {0.2, val12}};
List2 = {{0.0, val20}, {0.1, val21}, {0.2, val22}};

{#[[1, 1]], (#[[1, 2]] - #[[2, 2]])/#[[1, 2]]} & /@
Transpose[{List1, List2}]

(* {{0., (val10 - val20)/val10}, {0.1, (val11 - val21)/val11}, {0.2, (
val12 - val22)/val12}} *)


Or

Transpose@{List1[[All, 1]], (List1[[All, 2]] - List2[[All, 2]])/
List1[[All, 2]]}


Another way:

ListDiff = List1;
ListDiff[[All, 2]] -= List2[[All, 2]];
ListDiff[[All, 2]] /= List1[[All, 2]];

ListDiff


{{0., (val10 - val20)/val10}, {0.1, (val11 - val21)/val11}, {0.2, (val12 - val22)/val12}}

• Looks nice, thank you!
– newt
Dec 8, 2017 at 20:05

You might consider using Association objects instead. For example:

List1 = {{0.0, val10}, {0.1, val11}, {0.2, val12}};
List2 = {{0.0, val20}, {0.1, val21}, {0.2, val22}};

assoc1 = Association[Rule @@@ List1]
assoc2 = Association[Rule @@@ List2]


<|0. -> val10, 0.1 -> val11, 0.2 -> val12|>

<|0. -> val20, 0.1 -> val21, 0.2 -> val22|>

Arithmetic with associations acts on the values. So:

(assoc1 - assoc2)/assoc1


<|0. -> (val10 - val20)/val10, 0.1 -> (val11 - val21)/val11, 0.2 -> (val12 - val22)/val12|>

f1 = {#[[1, 1]], (#2 - #1)/#1 & @@ #[[All, 2]]} & /@ GatherBy[Join[##], First] &;
f2 = {#[[1, 1]], (#2 - #1)/#1 & @@ #[[All, 2]]} & /@ SplitBy[Sort@Join[##], First] &;

f1[List1, List2]


{{0., (-val10 + val20)/val10}, {0.1, (-val11 + val21)/ val11}, {0.2, (-val12 + val22)/val12}}

f1[List1, List2] == f2[List1, List2]


True

You can use $\texttt{Cases}$ and pattern-matching:

Cases[
Transpose[{List1, List2}],
{{n_, v1_}, {n_, v2_}} :> {n, (v2 - v1)/v1}
]

• Thanks for this!
– newt
Dec 8, 2017 at 20:05

You have a low reputation, so I'm assuming you are fairly new to Mathematica. As such, here is an inelegant (but easily understood) approach:

Table[
{List1[[i, 1]], (List1[[i, 2]] - List2[[i, 2]])/List1[[i, 2]]},
{i, Length[List1]}]


And a word of advice: Never use upper-case to start the name of a variable, as it may conflict with an internal function in Mathematica. This is especially concerning if your variable is List1--so close to the function List. And ListDiff might be similar to the 30 or so internal functions that begin with "List".

• Thank you very much. I thought I would have to write a cycle. Never get used to Tables... And, I'm assuming you forgot division symbol.
– newt
Dec 7, 2017 at 18:03

You can use MapThread.

MapThread[
{First[#1], First[1 - Rest[#2] / Rest[#1]]}&, {List1, List2}]


Evaluating the code above, returns

{ { 0. , 1 - val20/val10 },
{ 0.1, 1 - val21/val11 },
{ 0.2, 1 - val22/val12 } }


(input lists are concatenated so as to allow evaluation).

MapThread applies a function on tuples, taken in a successive manner from the input lists (see code above).

The first tuple, contains the first element from every input list, the second tuple consists of the second element in each input list and so on.

Since, in this example, we are dealing with only two input lists (List1 and List2), the function that is applied on successive input tuples, receives two arguments ie #1 and #2.

These, are numbered slots (see Slot). They stand for the successive inputs, fed into the function argument of MapThread.

In this particular case we are dealing with, both of them are lists, with two entries eg in the case of the first tuple, #1 stands for {0.0, val10} and #2 stands for {0.0, val20}.

Continuing with the example of the first input tuple, evaluating First[#1] returns 0. (this is the First item in {0.0, val10}) while Rest[#1] returns {val01} (the second entry of {0.0,val10}-notice the braces).

Similarly, Rest[#2] returns {val20} (because #2 is equal to {0.0, val20}) and if we combine all the parts of the function together we get {0.,1-val20/val10}.

The rest of the output is constructed along similar lines.

• Thank you for the detailed explanation!
– newt
Dec 8, 2017 at 20:06

Using Merge:

alist = {{0.0, val10}, {0.1, val11}, {0.2, val12}};
blist = {{0.0, val20}, {0.1, val21}, {0.2, val22}};

Merge[{Rule @@@ alist,
Rule @@@ blist}, (First@# - Last@#)/(First@#) &] // Normal //
ReplaceAll[Rule -> List] // Column


Result:

l1 = {{0.0, val10}, {0.1, val11}, {0.2, val12}};
l2 = {{0.0, val20}, {0.1, val21}, {0.2, val22}};


Using Thread and MapApply:

{#1[[1]], 1 - #2[[2]]/#1[[2]]} & @@@ Thread[{l1, l2}]


Result:

Or using GroupBy:

l3 = Catenate[{l1, l2}];

gby = GroupBy[l3, #[[1]] &, 1 - #2/#3 & @@ Union@## & @@ Transpose@# &]



Result:

a = {{0.0, val10}, {0.1, val11}, {0.2, val12}};
b = {{0.0, val20}, {0.1, val21}, {0.2, val22}};


Using MapApply (new in 13.1)

{c, d} = Association @* MapApply[Rule] /@ {a, b};


Display as Dataset

(c - d) / c // Dataset


Convert to List

(c - d) / c // KeyValueMap[List] // TableForm


If we want to change a and b inline, we can use ApplyTo (new in 12.2)

{a, b} //= Map[Association @* MapApply[Rule]];

(a - b) / a // Dataset


(* output like above *)