5

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.

FalafelPita
  • 845
  • 5
  • 16

4 Answers4

5
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

eldo
  • 67,911
  • 5
  • 60
  • 168
3
Missing[] /. First@*Solve /@ Thread[Mean[{list1, list2}] == Missing[]]

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

Coolwater
  • 20,257
  • 3
  • 35
  • 64
2

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}
Ali Hashmi
  • 8,950
  • 4
  • 22
  • 42
2
Query[Mean] /@ Transpose[listOfLists] /. Mean[{}] -> Missing[]

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

kglr
  • 394,356
  • 18
  • 477
  • 896