4
$\begingroup$

I have a List of Associations that contains a Key called "ClaimBasis". There are about 10 possible values that ClaimBasis can take on, one of them being the value Null. I want all values that are equal to "Risks Attaching" to be changed to "RA". I want all other values for ClaimBasis to be changed to "LO". I originally tried to do this with an if statement, but the Null values caused me a problem. Below is what I am currently doing, and it works for now.

cBasis = Complement[
Union[#[ClaimBasis] & /@ businessAssoc], {"Risks Attaching"}];

businessAssoc = businessAssoc /. Alternatives @@ cBasis -> "LO" 
/. "Risks Attaching" -> "RA";

My concern is that in some future case I may have Null values assigned to other Keys in my List of Associations, and I wouldn't want to change them. The way I've been adjusting values in a List of Associations is as follows:

accAssoc = <|#, "Year" -> Floor[#Year]|> & /@ accAssoc;

or even

elrAssoc = <|#, If[#[EPI] != 0, LR -> #[Loss]/#[EPI], LR -> 0]|> & /@ elrAssoc;

What I would like to know is whether there's a sensible way to use Alternatives when changing a value for a specific Key in a List of Associations. Perhaps my "default" method for setting values in a List of Associations is not the best way to do it, in which case I'd appreciate knowing a better alternative.

Sample data as requested:

businessAssoc[[;; 15]]

{<|Treaty -> "<N/A>", Effective -> {1925, 1, 1, 0, 0, 0.}, ClaimBasis -> Null|>,
<|Treaty -> "14700", Effective -> {2007, 7, 1, 0, 0, 1.}, ClaimBasis -> "Occurrence"|>,
<|Treaty -> "87299", Effective -> {2001, 4, 1, 0, 1, 0.}, ClaimBasis -> Null|>,
<|Treaty -> "IN0004", Effective -> {1980, 5, 1, 0, 0, 0.}, ClaimBasis -> "<None>"|>,
<|Treaty -> "ABC0002", Effective -> {1988, 1, 1, 0, 0, 0.}, ClaimBasis -> "<None>"|>,
<|Treaty -> "TRES500B", Effective -> {2013, 1, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "YYYY434", Effective -> {2012, 7, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "TT48425", Effective -> {2003, 11, 3, 0, 1, 0.}, ClaimBasis -> "Occurrence"|>,
<|Treaty -> "TY4176A", Effective -> {2011, 1, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "MBM0001", Effective -> {1989, 7, 1, 0, 0, 0.}, ClaimBasis -> "<None>"|>,
<|Treaty -> "EEML216C", Effective -> {2007, 1, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "78820", Effective -> {1994, 6, 12, 0, 1, 0.}, ClaimBasis -> "Claims Made"|>,
<|Treaty -> "AMUT0004", Effective -> {1999, 1, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "CMMM0028", Effective -> {1997, 1, 1, 0, 0, 0.}, ClaimBasis -> "Losses Occurring"|>,
<|Treaty -> "TYCS1234", Effective -> {2012, 6, 15, 0, 0, 0.}, ClaimBasis -> "Risks Attaching"|>}

After the adjustment:

businessAssoc[[;; 15]]

{<|Treaty -> "<N/A>", Effective -> {1925, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
 <|Treaty -> "14700", Effective -> {2007, 7, 1, 0, 0, 1.}, ClaimBasis -> "LO"|>,
<|Treaty -> 87299", Effective -> {2001, 4, 1, 0, 1, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "IN0004", Effective -> {1980, 5, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "ABC0002", Effective -> {1988, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "TRES500B", Effective -> {2013, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>, 
<|Treaty -> "YYYY434", Effective -> {2012, 7, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "TT48425", Effective -> {2003, 11, 3, 0, 1, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "TY4176A", Effective -> {2011, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "MBM0001", Effective -> {1989, 7, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>, 
<|Treaty -> "EEML216C", Effective -> {2007, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>, 
<|Treaty -> "78820", Effective -> {1994, 6, 12, 0, 1, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "AMUT0004", Effective -> {1999, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "CMMM0028", Effective -> {1997, 1, 1, 0, 0, 0.}, ClaimBasis -> "LO"|>,
<|Treaty -> "TYCS1234", Effective -> {2012, 6, 15, 0, 0, 0.}, ClaimBasis -> "RA"|>}
$\endgroup$
1
  • $\begingroup$ It will be much easier to answer if you provide some sample data, to make your question self - contained. $\endgroup$ Jun 19, 2015 at 20:36

3 Answers 3

1
$\begingroup$

Similar to Albert Retey's answer but without in-place modification, you can use MapAt:

MapAt[
 Replace[{"Risks Attaching" -> "RA", _ -> "LO"}],
 businessAssoc,
 {All, Key @ ClaimBasis}
]

Map and Function can also be used:

<|#, ClaimBasis -> (#[ClaimBasis] /. {"Risks Attaching" -> "RA", _ -> "LO"})|> & /@
  businessAssoc
$\endgroup$
1
  • $\begingroup$ I like the one using Map and Function. $\endgroup$ Jun 20, 2015 at 21:28
6
$\begingroup$

I'm not sure whether that solves all the questions you have, but one of the really good things about Associations is that you can set content in place, like:

businessAssoc[[All, Key@ClaimBasis]] = Replace[
  businessAssoc[[All, Key@ClaimBasis]], {
   "Risks Attaching" -> "RA",
   _ -> "LO"
  },
  {1}
 ]

with the above you are only changing values associated to the ClaimBasis-key, so you don't even have to care about what values there are for the other keys...

$\endgroup$
1
  • $\begingroup$ It works perfectly, thanks. $\endgroup$ Jun 20, 2015 at 21:29
2
$\begingroup$

Addressing another part of your question, Consider this alternative method of updating a list of associations.

SeedRandom[1];
d1 = Table[Association["x" -> i, "y" -> RandomReal[{1950, 2000}]], {i, 10000}];
AbsoluteTiming[d1[[All, "y"]] = Floor[data[[All, "y"]]];] 
{0.008784, Null}

The above tests out as faster than the method you propose.

SeedRandom[1];
d2 = Table[Association["x" -> i, "y" -> RandomReal[{1950, 2000}]], {i, 10000}];
AbsoluteTiming[d2 = <|#, "y" -> Floor[#y]|> & /@ d2;]
{0.030963, Null}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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