6

These are distinct but related questions about mapping functions to Associations and Datasets. Given:

assoc = <| a -> 1, b -> 2, c -> 3|> 

And

data = 
 Dataset@{<| a -> 1, b -> 2, c -> 3|> , <|a -> 4, b -> 5, c -> 6|>}

Re MapAt:

MapAt[Framed, Key[b]][assoc] 

enter image description here

Although Dataset is not explicitly mentioned in the doc page for MapAt, it's supposed to apply to generic expressions. However:

MapAt[Framed, Key[b]][data]

enter image description here

Next, consider mapping over a named Key with this syntax:

data[All, {Key[b] -> Framed}] // Normal

enter image description here

Why don't the following variations work on Dataset?

data[All, Key[b] -> Framed] // Normal

enter image description here

data[All, Key[b] -> Framed[#] &] // Normal

enter image description here

Finally, back to Association:

assoc[Key[b] -> Framed] // Normal

enter image description here

alancalvitti
  • 15,143
  • 3
  • 27
  • 92

1 Answers1

11

That MapAt[Framed, Key[b]][data] doesn't work is a bug, which I'll fix (thanks!).

On the other hand, data[All, Key[b] -> Framed] is not a supported syntax for doing applying a function to a specific part. You have to have the enclosing list.

As for data[All, Key[b] -> Framed[#] &], the second query element there is a pure function. Pure functions get applied to the corresponding part of the Dataset, so the behavior you see is absolutely correct (and of course, useless).

In assoc[Key[b] -> Framed], you're doing a key-lookup on an association via function application. In particular you're looking up the key Key[b] -> Framed, which doesn't exist in the association. Hence you get Missing.

Taliesin Beynon
  • 10,639
  • 44
  • 51
  • Re "the second query element there is a pure function", how can generic functions with multiple arguments be passed, eg StringDrop[#,-1]&? - Of course can pass a predefined curried version but that's lame. – alancalvitti Jul 12 '14 at 13:52
  • @alancalvitti I think you are having a precedence problem. Is this what you want? data[All, {Key[b] -> (Framed[#] &)}] // Normal – Rojo Jul 12 '14 at 23:40
  • @alancalvitti I don't understand. StringDrop[#,-1]& is a pure function with a single argument. – Taliesin Beynon Jul 13 '14 at 00:25
  • @Rojo, thank you, that works. This precedence constraint isn't obvious to me, yet doesn't seem to be documented. – alancalvitti Jul 14 '14 at 18:37
  • @TaliesinBeynon, I mean that unlike Framed, which is a single argument function and can be passed as both Framed and Framed[#]&, how would you pass 2 argumen functions like StringDrop? However, Rojo simply parenthesized the pure function (of any # of arguments). Why isn't that documented? – alancalvitti Jul 14 '14 at 18:41
  • @alancalvitti it is just that a->b& is grouped as (a->b)& instead of a->(b&). It is a matter of precedence of the operators & versus ->. Operator precedence is documented (tutorial/OperatorInputForms). It is easy to check by repeatedly clicking on the expression (or ctrl+.) and seeing how the selection grows. You can also check the precedences with the undocumented Precedence/@{Function, Rule} but I don't think it is too useful – Rojo Jul 14 '14 at 18:50
  • Related to the bug: If data = Dataset@{<|"a" -> 1, b -> 2, c -> 3|>} then data[1, Key@"a"] -> 1 but not data[1,"a"]; i.e. is that Key is needed also a bug? – Ronald Monson Aug 02 '14 at 08:02