I have a dataset tds
that can be represented by the following code:
tdata = Flatten[
Table @@ #] & /@ {{i, {i, {"a", "b"}}, {12}}, {i, {2}, {i,
4}, {3}}, {i, {8}, {i, 3}}, {RandomVariate[
NormalDistribution[i, .01]], {2}, {i, 4}, {3}}} // Transpose;
tds = Dataset@
Map[Association@
MapThread[#1 -> #2 &, {{"series", "trial", "rep", "val"}, #}] &,
tdata]
The four columns represent an experiment name, trials, replicates and the values obtained. I would like to create a new dataset consisting of the series, trial columns with the val column being replaced by the average of the appropriate reps.
I can get the average of a particular series/trial with:
tds[Select[#series == "a" && #trial == 4 &] /* Mean, "val"]
(* 3.99244 *)
...and using GroupBy
allows me to get the average for each trial within a series:
With[{ds = tds[Select[#series == "a" &]]},
ds[GroupBy["trial"], <|"mean" -> Mean|>, "val"]
]
At this point, I can loop through all of the series names to get a dataset for each one:
Table[tds[Select[#series == i &]][GroupBy["trial"], <|"mean" -> Mean|>,
"val"], {i, {"a", "b"}}]
...but I don't know how to join these datasets or restore the now missing series information. This Q&A is useful if there are common keys, so that's not appropriate for my case, and I do not know how to modify this Q&A to Group by two columns rather than one.
Dataset
syntax, but I think this does what you want:tds[GroupBy[#, KeyTake[{"series", "trial"}] -> KeyTake["val"], Mean] &][Normal][All, Apply[Join]]
, adapted from this answer $\endgroup$