Skip to main content

One to Many Lists Merge


I have two lists:


list1 = {{1, A, AA}, {2, B, BB}, {3, C, CC}, {4, D, DD}, {6, F, FF}};

list2 = {{1, a, aa}, {1, b, bb}, {1, c, cc}, {2, d, dd}, {2, e, ee}, {3, f, ff},
{3, g, gg}, {3, h, hh}, {4, i, ii}, {4, j, jj}, {4, k, kk}, {4, l, ll},
{4, m, mm}, {5, n, nn}, {5, o, oo}, {7, p, pp}};

I want to merge these two lists. While merging list1 to list2, elements of list1 should be repeated or missing as shown below:




result = {{1, a, aa, A, AA}, {1, b, bb, A, AA}, {1, c, cc, A, AA}, {2, d, dd, B, BB}, 
{2, e, ee, B, BB}, {3, f, ff, C, CC}, {3, g, gg, C, CC}, {3, h, hh, C, CC},
{4, i, ii, D, DD}, {4, j, jj, D, DD}, {4, k, kk, D, DD}, {4, l, ll, D, DD},
{4, m, mm, D, DD}, {5, n, nn, Missing[], Missing[]},
{5, o, oo, Missing[], Missing[]}, {6, Missing[], Missing[], F, FF},
{7, p, pp, Missing[], Missing[]}};

Any help is greatly appreciated. Similarly, if we can merge above two lists plus the following list in a similar manner in one step, please help me.



list3 = {{2, .2, 20}, {3, .3, 30}, {4, .4, 40}, {5,.5, 50}, {6, .6, 60}};


Thank you all in advance.



Answer



Approach using v10 functions:


CustomMerge1[lists__] := Module[{assocList, keys, vals, res},
assocList = GroupBy[#, First -> Rest] & /@ {lists};
keys = Sort@DeleteDuplicates[Flatten[Keys /@ assocList]];
res = Table[
vals = #[k] /. Missing[___] -> {{Missing[], Missing[]}} & /@
assocList;

Flatten /@ Tuples[{{k}, Sequence @@ vals}]
, {k, keys}];
Flatten[res, 1]
];
CustomMerge1[list1, list2, list3]
(*{{1, A, AA, a, aa, Missing[], Missing[]}, {1, A, AA, b, bb, Missing[],
Missing[]}, {1, A, AA, c, cc, Missing[], Missing[]}, {2, B, BB, d,
dd, 0.2, 20}, {2, B, BB, e, ee, 0.2, 20}, {3, C, CC, f, ff, 0.3,
30}, {3, C, CC, g, gg, 0.3, 30}, {3, C, CC, h, hh, 0.3, 30}, {4, D,
DD, i, ii, 0.4, 40}, {4, D, DD, j, jj, 0.4, 40}, {4, D, DD, 4, kk,

0.4, 40}, {4, D, DD, l, ll, 0.4, 40}, {4, D, DD, m, mm, 0.4,
40}, {5, Missing[], Missing[], n, nn, 0.5, 50}, {5, Missing[],
Missing[], o, oo, 0.5, 50}, {6, F, FF, Missing[], Missing[], 0.6,
60}, {7, Missing[], Missing[], p, pp, Missing[], Missing[]}}*)

As you see this function work with any number of input lists


Comments

Popular posts from this blog

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

plotting - How to draw lines between specified dots on ListPlot?

I would like to create a plot where I have unconnected dots and some connected. So far, I have figured out how to draw the dots. My code is the following: ListPlot[{{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4,13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full] I have thought using ListLinePlot command, but I don't know how to specify to the command to draw only selected lines between the dots. Do have any suggestions/hints on how to do that? Thank you. Answer One possibility would be to use Epilog with Line : ListPlot[ {{1, 1}, {2, 2}, {3, 3}, {4, 4}, {1, 4}, {2, 5}, {3, 6}, {4, 7}, {1, 7}, {2, 8}, {3, 9}, {4, 10}, {1, 10}, {2, 11}, {3, 12}, {4, 13}, {2.5, 7}}, Ticks -> {{1, 2, 3, 4}, None}, AxesStyle -> Thin, TicksStyle -> Directive[Black, Bold, 12], Mesh -> Full, Epilog -> { Line[ ...