Error changing Dataset using Part
I'm the developer of Dataset
.
Yes, this is a gross documentation oversight. We planned this functionality but had to push it back to a point release. Somehow no-one caught this piece of legacy documentation.
I've filed a bug on the documentation problem right now, it's easy to fix.
As for when L-value assignment will be available, I'm hoping 10.0.1 or 10.0.2, which are in the next month or two. It gets complicated, because you might well want to write things like:
dataset[ Select[#age > 30&] , "salary"] *= 2
That's certainly a powerful kind of operation, but also hard to implement. Even part-like assignments can get complicated when you are assigning multidimensional datasets to each other.
Thanks for trying the functionality, though!
In lieu of Set
, the Query
syntax offers various ways to update selective elements of a dataset. For example, we can change the value of the field a
in the first row like this:
ds[{1 -> (<| #, "a" -> 999|> &)}]
or like this:
ds[{1 -> Query[{"a" -> (999 &)}]}]
Multiple fields can be updated simultaneously:
ds[{1 -> (<| #, "a" -> 999, "b" -> "ZZZ" |> &)}]
We can update selective rows, in this case field "b" in rows with even a
:
ds[All, If[EvenQ[#a], <| #, "b" -> "!!!!"|>, #] &]
The accumulation use case can be accomplished like this:
With[{a = ds[Accumulate, "a"]}
, ds @ MapIndexed[<| #, "a" -> a[[First@#2]] |> &]
]
or like this:
Module[{acc = 0}, ds[All, {"a" -> (acc += # &)}]]
Note that none of these operations involve destructively altering the dataset, so they should all read ds = ds[...]
if desired. Presumably Set
will eventually perform destructive updates in those restricted circumstances that Mathematica tolerates mutation.
Though I don't know what is the efficiency impact of it, a workaround could be converting the Dataset
to Association
by Normal
, making the update on the Association
, then converting it back to Dataset
.
ds = Dataset[{<|"a" -> 1, "b" -> "x"|>, <|"a" -> 2, "b" -> "y"|>, <|"a" -> 6, "b" -> "z"|>}]
ds = Module[{temp = Normal[ds]},
temp[[All, "a"]] = Accumulate[temp[[All, "a"]]];
temp // Dataset]