# Generating lists of data with ReplacePart

I have the following example:

data = {{a, a1, a2}, {b, b1, b2}, {c, c1, c2}, {d, d1, d2}};
repa = {a11, a12, a13};
repb = {b11, b12, b13};
repc = {c11, c12, c13};
newData =
ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2}] &, {repa, repb}]


Which generates:

{{{a, a11, a2}, {b, b11, b2}, {c, c1, c2}, {d, d1, d2}}, {{a, a12,
a2}, {b, b12, b2}, {c, c1, c2}, {d, d1, d2}}, {{a, a13, a2}, {b,
b13, b2}, {c, c1, c2}, {d, d1, d2}}}


Now, what if I want to continue in a similar way, and generate on this the following:

{...,{{a, a11, a2}, {b, b11, b2}, {c, c11, c2}, {d, d1, d2}}, {{a, a12,
a2}, {b, b12, b2}, {c, c12, c2}, {d, d1, d2}}, {{a, a13, a2}, {b,
b13, b2}, {c, c13, c2}, {d, d1, d2}}}


where the dots represent the expression above without the outer {} or even something uglier by making the copy of the above and then extending it by replacing d1->{d11,d12,d13} analogously? What would be the best way? Also is there a way without stacking the operators which implies that i have to know how many variations I need to make?

Also I would be glad with any comments, on the current implementation of MapThread+ReplacePart, is there a better way?

• At least, you can do MapThread[ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2, {3, 2} -> #3, {4, 2} -> #4}] &, {repa, repb, repc, repd}], because MapThread is generalizable to more than two inputs, but there's certainly a better way. I will think on it. – march Mar 12 '16 at 0:29

The direct generalization of your code would be to take advantage of the fact that MapThread works for functions with more than two arguments. Therefore, if

data = {{a, a1, a2}, {b, b1, b2}, {c, c1, c2}, {d, d1, d2}};
repa = {a11, a12, a13};
repb = {b11, b12, b13};
repc = {c11, c12, c13};
repd = {d11, d12, d13};


then

newData = MapThread[
ReplacePart[data, {{1, 2} -> #1, {2, 2} -> #2, {3, 2} -> #3, {4, 2} -> #4}] &,
{repa, repb, repc, repd}
]
(* { {{a, a11, a2}, {b, b11, b2}, {c, c11, c2}, {d, d11, d2}},
{{a, a12, a2}, {b, b12, b2}, {c, c12, c2}, {d, d12, d2}},
{{a, a13, a2}, {b, b13, b2}, {c, c13, c2}, {d, d13, d2}} } *)


We can automate this somewhat via the following:

newData = With[
{f = Table[{j, 2} -> Slot[j], {j, 4}]},
MapThread[ReplacePart[data, f] &, {repa, repb, repc, repd}]
]


The following method has the advantage of not requiring hard-coding the number of lists (i.e. 4 for a, b, c, and d in this case), but it has the disadvantage of not working if there are repeated elements in the each sublist of data:

newData = Transpose@MapThread[
#1 /. List /@ Thread[#1[[2]] -> #2] &,
{data, {repa, repb, repc, repd}}
]