8

After a left JoinAcross, I have a number of Missing["Unmatched"] values in my list of associations. I'd like to set them all equal to zero. I tried the following:

q = JoinAcross[Normal[reported], Normal[estimates], Key["key"], "Left"];
q1 = q /. Missing["Unmatched"] -> 0;
q[[100]]
q1[[100]]
<|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, 
  "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, 
  "DLI" -> 25619.3, "EstimatesEP" -> Missing["Unmatched"]|>

<|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, "DLI" -> 25619.3, "EstimatesEP" -> Missing["Unmatched"]|>

Edit

I neglected to mention that I need to do this to the entire list of associations. I used element 100 as an example.

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
Mitchell Kaplan
  • 3,696
  • 22
  • 34

2 Answers2

5

A couple of alternatives:

assoc = <|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, 
   "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, 
   "DLI" -> 25619.3, "EstimatesEP" -> Missing["Unmatched"]|>;

Map[# /. Missing["Unmatched"] -> 0 &, assoc]
(*
  <|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, 
   "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, 
   "DLI" -> 25619.3, "EstimatesEP" -> 0|>
*)

Block[{Missing},
 Missing["Unmatched"] = 0;
 Map[Identity, assoc]
 ]
(*
  <|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, 
   "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, 
   "DLI" -> 25619.3, "EstimatesEP" -> 0|>
*)
Michael E2
  • 235,386
  • 17
  • 334
  • 747
3

In general you can supply default values like this:

defaults = <|"EstimatesEP" -> 0|>;
data = <|"key" -> "2009-ABCDE", "ActuarialEPI" -> 26603.6, 
   "ReportedEP" -> 28535., "ReportedLI" -> 0., "ELI" -> 25619.3, 
   "DLI" -> 25619.3, "EstimatesEP" -> Missing["Unmatched"]|>;

<|defaults, DeleteMissing@data|>
<|"EstimatesEP" -> 0, "key" -> "2009-ABCDE", 
 "ActuarialEPI" -> 26603.6, "ReportedEP" -> 28535., 
 "ReportedLI" -> 0., "ELI" -> 25619.3, "DLI" -> 25619.3|>

In order to set any key to zero by default you can use

default = AssociationThread[Keys[data] -> ConstantArray[0, Length@Keys[data]]];
<|"key" -> 0, "ActuarialEPI" -> 0, "ReportedEP" -> 0, 
 "ReportedLI" -> 0, "ELI" -> 0, "DLI" -> 0, "EstimatesEP" -> 0|>

This solution can easily be applied to a list of Associations:

data2 = ConstantArray[data, 3];
<|defaults, DeleteMissing@#|> & /@ data2
C. E.
  • 70,533
  • 6
  • 140
  • 264
  • Thanks your solution works, but I don't understand it. In the simpler case with just 1 element in the association, how does <|defaults, DeleteMissing@data|> do the substitution? – Mitchell Kaplan Aug 25 '14 at 15:31
  • @MitchellKaplan Please read this including especially WReach's answer to that question, which establishes the rules that Asssociation adheres to. Association flattens its arguments and when the same key appears several times the last key always wins. In my solution default precedes data so it is usually overwritten, but when I delete keys with missing values defaults will not be overwritten for those keys. – C. E. Aug 25 '14 at 15:42