# Unexpected output of ReplaceAll

Each week I import a dataset, and every week the dataset differs in length (the number of records). After the import I need to do some transformations. One of these transformations is the ReplaceAll.

problem: when the number of records is the same length of the number of parameters in de transformations, the ReplaceAll won't give the desired output.

For example:

data1 = {{"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2",
"E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4",
"E4"}, {"A5", "B5", "C5", "D5", "E5"}};

data1 /. {a_ , b_, c_ , d_ , e_} -> {"T", a , b, c, d, e}


The output is:

{"T", {"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2", "E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4", "E4"}, {"A5", "B5", "C5", "D5", "E5"}}

When the number of records differ from the number of parameters in the ReplaceAll function, like this:

data2 = {{"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2",
"E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4",
"E4"}};

data2 /. {a_ , b_, c_ , d_ , e_} -> {"T", a , b, c, d, e}


Now I get the output I want.

{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2", "E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4", "D4", "E4"}}

The same is truth for a list with six records:

data3 = {{"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2",
"E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4",
"E4"}, {"A5", "B5", "C5", "D5", "E5"}, {"A6", "B6", "C6", "D6",
"E6"}}

data3 /. {a_ , b_, c_ , d_ , e_} -> {"T", a , b, c, d, e}


{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2", "E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4", "D4", "E4"}, {"T", "A5", "B5", "C5", "D5", "E5"}, {"T", "A6", "B6", "C6", "D6", "E6"}}

Who has a suggestion for this problem?

Use Replace with a level specification instead:

data1 = {
{"A1","B1","C1","D1","E1"},
{"A2","B2","C2","D2","E2"},
{"A3","B3","C3","D3","E3"},
{"A4","B4","C4","D4","E4"},
{"A5","B5","C5","D5","E5"}
};

Replace[
data1,
{a_,b_,c_,d_,e_}->{"T",a,b,c,d,e},
{1}
]


{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2", "E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4", "D4", "E4"}, {"T", "A5", "B5", "C5", "D5", "E5"}}

Try Prepend

Prepend[#, "T"] & /@ data1


{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2", "E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4", "D4", "E4"}, {"T", "A5", "B5", "C5", "D5", "E5"}}

Besides, {a_ , b_, c_ , d_ , e_} -> {"T", a , b, c, d, e} can be written as {a__} -> {"T", a} , if the list is not empty.

Or you can try

# /. {a__} :> {"T", a} & /@ {{"A1", "B1", "C1", "D1", "E1"}, {"A2",
"B2", "C2", "D2", "E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4",
"B4", "C4", "D4", "E4"}, {"A5", "B5", "C5", "D5", "E5"}}


It is because _ operator starts at top where it found List and only if number of elements in list are same as _(as a requirement of _), it will recognize it otherwise it will go down to elements of each list. Say you do a small test,

data2 /. {a_, b_, c_, d_, e_} /; ListQ[a] -> {"T", a, b, c, d, e}


It returns,

{{"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2",
"E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4",
"E4"}}


Nothing processed because pattern didn't match.

To solve it, something on these line,

data2 //. {a___, {b_, c_, d_, e_, f_},
g___} :> {a, {"T", b, c, d, e, f}, g}

{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2",
"E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4",
"D4", "E4"}}

• Oke, thanks, But do you have a solution for my problem Commented Nov 9, 2020 at 13:28
list =
{{"A1", "B1", "C1", "D1", "E1"},
{"A2", "B2", "C2", "D2", "E2"},
{"A3", "B3", "C3", "D3", "E3"},
{"A4", "B4", "C4", "D4", "E4"},
{"A5", "B5", "C5", "D5", "E5"}};


Using ReplaceAll with AtomQ

list /. {a__?AtomQ} :> {"T", a} // MatrixForm


Using Cases

Cases[list, a_ :> Prepend[a, "T"]] // MatrixForm


list =
{{"A1", "B1", "C1", "D1", "E1"},
{"A2", "B2", "C2", "D2", "E2"},
{"A3", "B3", "C3", "D3", "E3"},
{"A4", "B4", "C4", "D4", "E4"},
{"A5", "B5", "C5", "D5", "E5"}};


Using ReplaceList:

ReplaceList[list, {___, s : {a_, b__}, ___} :> Prepend[s, "T"]] // MatrixForm


data1 = {{"A1", "B1", "C1", "D1", "E1"}, {"A2", "B2", "C2", "D2",
"E2"}, {"A3", "B3", "C3", "D3", "E3"}, {"A4", "B4", "C4", "D4",
"E4"}, {"A5", "B5", "C5", "D5", "E5"}};

data1 /. x_?VectorQ :> {"T"}~Join~x


{{"T", "A1", "B1", "C1", "D1", "E1"}, {"T", "A2", "B2", "C2", "D2",
"E2"}, {"T", "A3", "B3", "C3", "D3", "E3"}, {"T", "A4", "B4", "C4",
"D4", "E4"}, {"T", "A5", "B5", "C5", "D5", "E5"}}

In human language the above will be parsed roughly as:

If x_ matches a vector of elements then prepend "T" to this vector called x.

In the example posted by OP, {a_, b_, c_, d_, e_} would match five items, including five lists (if that is the case). When that happens, the replacements happen at the main level as opposed to the sublist level where these are intended. A further differentiation must be included to limit replacements to the sublist level only.