5
$\begingroup$

I understand, from Calculating the mean of a list with NaN values, that one can preserve structured data with missing values, and still calculate a mean, using Mean[DeleteMissing[]]. I want to extend that to a vector, or list of lists. The Mean function handles list of lists that don't have missing values just fine.

obs1 = {2,3,1,7};
obs2 = {1,1,2,1};
Mean[{obs1,obs2}]

Results

{3/2, 2, 3/2, 4}

And removing missing values to calculate a scalar mean is straightforward

list1 = {Missing[], 2, 3, Missing[], 6};
Mean[DeleteMissing[list1]]

Results

11/3

However, I haven't been able to figure out how to perform the analogous calculation for a vector.

list1 = {Missing[], 2, 3, Missing[], 6};
list2 = {4, Missing[], 1, Missing[], 1};
listOfLists= {list1,list2};
Mean[DeleteMissing[listOfLists]]
Mean[DeleteMissing[listOfLists,2]]

Results

{1/2 (4 + Missing[]), 1/2 (2 + Missing[]), 2, Missing[], 7/2}
{3, 2, 7/2}

The first attempt fails to ignoring the missing values (they aren't deleted), and the second result completely distorts the intended calculation by losing the structure of the data because the missing values are deleted.

The documentation for `Mean' states

$$ \text{Mean}\left[\left\{\left\{x_1,y_1,\ldots \right\},\left\{x_2,y_2,\ldots \right\},\ldots \right\}\right] \text{ gives } \left\{\text{Mean}\left[\left\{x_1,x_2,\ldots \right\}\right],\text{Mean}\left[\left\{y_1,y_2,\ldots \right\}\right]\right\} $$

So it seems to me that what I want to do is to have DeleteMissing occur after the list of lists has been restructured, but before calculating the means of the individual lists.

What would be an efficient way to do this?

Edit/Update: The solution I'm looking for would produce either {4,2,2,Missing[],7/2} or {4,2,2,7/2}, in which case I would figure out separately which values were completely missing.

$\endgroup$
2
$\begingroup$
Query[Mean] /@ Transpose[listOfLists] /. Mean[{}] -> Missing[]

{4, 2, 2, Missing[], 7/2}

$\endgroup$
  • $\begingroup$ With V10 you get Missing[Indeterminate], so you don't even need the final replacement - +1 of course :) $\endgroup$ – eldo Jul 12 '17 at 21:20
  • $\begingroup$ Thank you @eldo. In $CloudVersion 1.142.1 I get Mean[{}] . $\endgroup$ – kglr Jul 12 '17 at 21:26
5
$\begingroup$
Mean /@ DeleteMissing /@ listOfLists

enter image description here

Or

Mean@*DeleteMissing /@ listOfLists

where @* is a short form of Composition

Or

Mean /@ DeleteMissing[listOfLists, 2]

where 2 is a Level specification

To answer your Update:

Mean /@ (Transpose[{list1, list2}] /. {a_, Missing[]} | {Missing[], a_} :> {a, a})

Or

Map[Mean]@Transpose[{list1, list2}] /. Plus[a_, Missing[]] :> 2 a

enter image description here

$\endgroup$
3
$\begingroup$
Missing[] /. First@*Solve /@ Thread[Mean[{list1, list2}] == Missing[]]

{4, 2, 2, Missing[], 7/2}

$\endgroup$
2
$\begingroup$

2nd part of your question:

list1 = {Missing[], 2, 3, Missing[], 6};
list2 = {4, Missing[], 1, Missing[], 1};

MapThread[If[FreeQ[{##}, Missing[]], Mean[{##}], 
Complement[{##}, {Missing[]}]] &, {list1, list2}] /. {} :> Missing[] // Flatten
(* {4, 2, 2, Missing[], 7/2} *)

with DeleteCases:

Mean@DeleteCases[#, _Missing] & /@ {list1, list2}
$\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.