# Mathematical operation on two lists by a “key” [duplicate]

I'm a complete newb here. Just looking for direction. I've got two lists like this...

list1 = {{{2014, 9, 2}, 4.18}, {{2014, 9, 3}, 4.17}, {{2014, 9, 4}, 4.18}, {{2014, 9, 5},
4.17}, {{2014, 9, 8}, 4.13}, {{2014, 9, 9}, 4.15}, {{2014, 9, 10},
4.08}, {{2014, 9, 11}, 4.03}, {{2014, 9, 12}, 4.06}, {{2014, 9, 15},
3.98}, {{2014, 9, 16}, 3.89}, {{2014, 9, 17}, 3.82}, {{2014, 9, 18},
3.88}, {{2014, 9, 19}, 3.93}, {{2014, 9, 22}, 3.81}, {{2014, 9, 23},
3.76}, {{2014, 9, 24}, 3.71}, {{2014, 9, 25}, 3.7}, {{2014, 9, 26},
3.63}, {{2014, 9, 29}, 3.56}, {{2014, 9, 30}, 3.56}, {{2014, 10, 1},
3.39}, {{2014, 10, 2}, 3.37}, {{2014, 10, 3}, 3.43}, {{2014, 10, 6},
3.42}, {{2014, 10, 7}, 3.35}, {{2014, 10, 8}, 3.3}, {{2014, 10, 9},
3.03}, {{2014, 10, 10}, 2.95}, {{2014, 10, 13}, 2.78}, {{2014, 10, 14},
2.61}, {{2014, 10, 15}, 2.62}, {{2014, 10, 16}, 2.56}, {{2014, 10, 17}, 2.67}};

list2 = {{{2014, 9, 2}, 4.16}, {{2014, 9, 3}, 4.19}, {{2014, 9, 4}, 4.15}, {{2014, 9, 5},
4.15}, {{2014, 9, 8}, 4.13}, {{2014, 9, 9}, 4.08}, {{2014, 9, 10},
4.08}, {{2014, 9, 11}, 4.08}, {{2014, 9, 12}, 3.96}, {{2014, 9, 15},
3.91}, {{2014, 9, 16}, 3.81}, {{2014, 9, 17}, 3.82}, {{2014, 9, 18},
3.88}, {{2014, 9, 19}, 3.81}, {{2014, 9, 22}, 3.76}, {{2014, 9, 23},
3.69}, {{2014, 9, 24}, 3.7}, {{2014, 9, 25}, 3.63}, {{2014, 9, 26},
3.6}, {{2014, 9, 29}, 3.55}, {{2014, 9, 30}, 3.41}, {{2014, 10, 1},
3.35}, {{2014, 10, 2}, 3.39}, {{2014, 10, 3}, 3.4}, {{2014, 10, 6},
3.36}, {{2014, 10, 7}, 3.28}, {{2014, 10, 8}, 3.28}, {{2014, 10, 9},
2.95}, {{2014, 10, 10}, 2.72}, {{2014, 10, 13}, 2.74}, {{2014, 10, 14},
2.62}, {{2014, 10, 15}, 2.61}, {{2014, 10, 16}, 2.64}, {{2014, 10, 17}, 2.72}};


How can I subtract (or perform any operation on) list one values from list two values using the date as the 'key'? The resulting list would have a dates and the result from the operation on list one and list two. In other words, with the example lists above, the output value would start with {{{2014,9,2},-0.02},...

• First a question for you: are you using version 10? – Mr.Wizard Oct 19 '14 at 2:32
• @Mr.Wizard FWIW, do you know if there is some indicator provided by the site that the page is being edited? You beat me by a few seconds, and it would be helpful to know that someone is already working on edits. – bobthechemist Oct 19 '14 at 2:33
• @bobthechemist Sadly, no. I've had that happen to me quite a few times too. Perhaps you should propose something on meta.stackexchange.com – Mr.Wizard Oct 19 '14 at 2:47
• I'm actually using the wolfram language. Is that version 10 of mathematica ? – Josh Millstein Oct 20 '14 at 1:17

If you have version 10 you can also use

List@@@Normal@GroupBy[Join[list1,list2],First->Last,#[[2]]-#[[1]]&]

  {{{2014,9,2},-0.02},{{2014,9,3},0.02},{{2014,9,4},-0.03},{{2014,9,5},-0.02},
{{2014,9,8},0.},{{2014,9,9},-0.07},{{2014,9,10},0.},{{2014,9,11},0.05},
...
{{2014,10,16},0.08},{{2014,10,17},0.05}}


For version 9

{#[[1,1]],#[[All,2]][[2]]-#[[All,2]][[1]]}&/@GatherBy[Join[list1,list2],First]


or

{#[[1,1]],Subtract@@Reverse[#[[All,2]]]}&/@GatherBy[Join[list1,list2],First]


gives the same result.

If you have version 10 with Association and related functionality, and if all keys are present in both:

<|Rule @@@ list2|> - <|Rule @@@ list1|>

<|{2014, 9, 2} -> -0.02, {2014, 9, 3} -> 0.02, ... {2014, 10, 17} -> 0.05|>


If some keys are missing from one list or the other you could start with KeyIntersection:

Subtract @@ KeyIntersection[{Rule @@@ list2, Rule @@@ list1}]


For earlier versions assuming no key is duplicated with a single list:

Cases[Join[list2, list1] ~GatherBy~ First, {{d_, n2_}, {_, n1_}} :> {d, n2 - n1}]

{{{2014, 9, 2}, -0.02}, {{2014, 9, 3}, 0.02}, ... {{2014, 10, 17}, 0.05}}