# The equivalent of dplyr mutate with Dataset

In R, there is a package "dplyr" that works on data.frame objects, which is one of the origins of the Mathematica Dataset construct. One of the things dplyr can do is "mutate" the columns of a data.frame. Here is an example that I hope will be self explanatory. Consider a data.frame df with columns a, b and c. I want to change column b so that it is a^2 and I then want to change column c so that it is 2*b, where b is the new value of b. (Yes, I know there is a computational shortcut).

 df %>% mutate(b = a^2,c=2b)


Here is how we could do the equivalent thing in Mathematica.

 mutate[df_,rules_]:=Fold[{s, r} \[Function] Query[All, ReplacePart[#, r]  &]@s, df, rules]


Example

 mutate[dataset,{"b" -> #a^2, "c" -> 2*#b}]


Does anyone have any better ideas or ways to generalize this? And, yes one can use RLink to actually use dplyr directly, but for the moment I want to stick with pure Mathematica.

• Generalize towards what? – alancalvitti Oct 6 '15 at 1:14
• Yes, if you had only two rules for altering the contents of the columns, your way might work. But I do not think it is practical for altering, say, 20 columns. As for whether the function is needed, I think if you talk to the R community, you would find that mutate from the dplyr package is one of the most heavily used functions in data analysis and that the convenience of being able to write a single mutate in which subsequent transformations can use prior transformations is extremely useful. – Seth Chandler Oct 7 '15 at 16:07
• I deleted my earlier comment as it did not work as expected, but also took a stab at a composable operator, below. – alancalvitti Oct 7 '15 at 18:02
• @SethChandler +1 Your solution looks quite good, I have something very very similar (still using Fold) but there are some other approaches also. Could you develop what you mean by "... generalize this" ? – SquareOne Oct 31 '15 at 1:58

Partial workaround, in operator form:

mutate[k_ -> f_][a_Association] := Insert[a, k -> f[a], Key[k]];


Eg,

ds = {<|"a" -> 1, "b" -> 3, "c" -> 5|>, <|"a" -> 2, "b" -> 4,
"c" -> 6|>} // Dataset


ds[All, mutate["b" -> (#a^2 &)] /* mutate["c" -> (2 #b &)]]


Those skilled in pattern matching can define mutate to take a list of rules and wrap RightComposition around them.

ds = {<|"a" -> 1, "b" -> 3, "c" -> 5|>, <|"a" -> 2, "b" -> 4,