7
$\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 Answers 6

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

MatrixForm[subs[mat]]
$\endgroup$
3
  • 1
    $\begingroup$ You have typo. It is Blank not Blanck :) $\endgroup$
    – Nasser
    Nov 23, 2017 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, 2017 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$ Nov 23, 2017 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$
3
$\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$

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$

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 and acknowledge you have read our privacy policy.

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