row operations in matrix

I got a matrix which has Error and Blank inside. I have to replace Error with Max - Min of its row and replace Blank with mean of its row.

When I tried to do it, I couldn't do the Max - Min because of Error word in the row.

Could someone help?

mat = RandomReal[{0,2},{10,10}];

mat[[1,3]] = mat[[6,8]] = mat[[4,4]] = mat[[10,5]] = "Error";

mat[[2,8]] = mat[[5,3]] = mat[[4,7]] = mat[[8,7]] = "Blank";

mat//MatrixForm


Guys, little change, Blank should be mean of its column,..

subs[mat_] :=(bl = Mean[Select[#, NumericQ]];
er = Differences[MinMax[Select[#, NumericQ]]][[1]];
# /. {"Blank" -> bl, "Error" -> er}) & /@ mat;

MatrixForm[subs[mat]]

• You have typo. It is Blank not Blanck :) Commented Nov 23, 2017 at 11:28
• Thanks @Nasser. For a moment I was worried that I might have done something right on the first attempt ;) Commented Nov 23, 2017 at 11:31
• I recommend using NumericQ instead of NumberQ. NumberQ will not work with matrices that contain mathematical constants like Pi. Commented Nov 23, 2017 at 12:22

Define helper function:

replaceErrorAndBlank[row_List] := Module[{
numericEntries = Select[row, NumericQ],
minMax,
mean
},
minMax = Subtract @@ Reverse[MinMax @ numericEntries];
mean = Mean[numericEntries];
Replace[row, {"Error" -> minMax, "Blank" -> mean}, {1}]
];


Map over the matrix:

replaceErrorAndBlank /@ mat // MatrixForm


Make data

mat = RandomReal[{0, 2}, {10, 10}];
mat[[1, 3]] = mat[[6, 8]] = mat[[4, 4]] = mat[[10, 5]] = "Error";
mat[[2, 8]] = mat[[5, 3]] = mat[[4, 7]] = mat[[8, 7]] = "Blank";


Fix

err    = Position[mat, "Error"];
blank  = Position[mat, "Blank"];
tmp    = ReplacePart[mat, Join[err, blank] -> Nothing];

maxmin = (z = tmp[[First@#]];  Max[z] - Min[z]) & /@ err;
mean   = (z = tmp[[First@#]];  Mean[z])         & /@ blank;



Maybe a more complex alternative, without defining auxiliary function:

((#[[2]] /. #[[1]]) & /@
Transpose@{(Which[
Cases[#, _String] == {"Error"},
"Error" -> Abs@(Subtract @@ MinMax[Select[#, NumericQ]]),
Cases[#, _String] == {"Blank"},
"Blank" -> Mean[Select[#, NumericQ]],
Cases[#, _String] == {"Error", "Blank"},
{"Error" -> Abs@(Subtract @@ MinMax[Select[#, NumericQ]]),
"Blank" -> Mean[Select[#, NumericQ]]},
Cases[#, "Error" || "Blank"] == {}, {}] & /@ mat),
mat}) // MatrixForm


You may use functions from Function Composition & Operator Forms (e.g. Composition and Through) and functions from Applying Functions to Lists (e.g. MapThread and Thread) to directly replace.

With mat defined with SeedRandom[123]; then

MapThread[
#1 /. Thread[{"Error", "Blank"} -> #2] &,
{
mat,
mat /. {"Error" | "Blank" -> Nothing} //
Map[Through@{First@*Differences@*MinMax, Mean}[#] &]
}] // MatrixForm


gives

Hope this helps.

I think the special behaviors of Query are the way to go here.

Let's set up a new matrix like so:

newMat = mat /. {"Blank" -> Missing["Blank"], "Error" -> Missing["Error"]}


Make a processing function like so:

f[row_] :=
row /.
{Missing["Error"] :> First@Differences[Query[MinMax]@row],
Missing["Blank"] :> Query[Mean]@row}


and do

f /@ newMat