6
$\begingroup$

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,..

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

MatrixForm[subs[mat]]
$\endgroup$
  • $\begingroup$ You have typo. It is Blank not Blanck :) $\endgroup$ – Nasser Nov 23 '17 at 11:28
  • $\begingroup$ Thanks @Nasser. For a moment I was worried that I might have done something right on the first attempt ;) $\endgroup$ – Sumit Nov 23 '17 at 11:31
  • 3
    $\begingroup$ I recommend using NumericQ instead of NumberQ. NumberQ will not work with matrices that contain mathematical constants like Pi. $\endgroup$ – Sjoerd Smit Nov 23 '17 at 12:22
5
$\begingroup$

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
$\endgroup$
2
$\begingroup$

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
$\endgroup$
2
$\begingroup$

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";

Mathematica graphics

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;

ReplacePart[mat, Join[Thread[err -> maxmin], Thread[blank -> mean]]]

Mathematica graphics

$\endgroup$
2
$\begingroup$

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

Mathematica graphics

Hope this helps.

$\endgroup$
2
$\begingroup$

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
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.