Applying a function to a Dataset column conditional on another slot's value
Here is one way:
data[All, MapAt[foo, #, #PLATFORM /. {"Dropbox" -> "LOCATION", _ -> {}}] &]
Or, if one prefers If
:
data[All, MapAt[foo, #, If[#PLATFORM == "Dropbox", "LOCATION", {}]] &]
Edit
The preceding expressions use MapAt
with a fixed function (foo
) and a conditional set of parts (either "LOCATION"
or an empty list). As @alancalvitti notes in the comments, MapAt
can also be used with a conditional function (either foo
or Identity
) against a fixed part ("LOCATION"
):
data[All, MapAt[If[#PLATFORM == "Dropbox", foo, Identity], #, "LOCATION"] &]
This is essentially the same as @LeonidShifrin's solution.
Edit 2 - Dynamic Query
We could also apply a dynamic query operator:
data[All, Query[If[#PLATFORM == "Dropbox", {"LOCATION" -> foo}, All]]@# &]
Perhaps, there is a better one, but here is one that comes to mind:
ClearAll[transform];
transform["Dropbox"] := foo;
transform[_] := Identity;
and then
data[All, With[{tr = transform[#PLATFORM]}, MapAt[tr, #, {Key["LOCATION"]}]] &]
Okay, this question is already answered, but I want to add my 'preferred way' here:
First, we define a new operator:
ApplyIf[f_, g_, x_] := If[TrueQ[f[x]], g[x], x];
ApplyIf[f_, g_][x_] := ApplyIf[f, g, x];
Then we do the query:
data[All, ApplyIf[#PLATFORM == "Dropbox"&, MapAt[foo, "LOCATION"]]]
I think it's pretty clear -- we're using composition to nicely separate the condition from the action.
ApplyIf
should probably exist in the core language. The particular compound Map[ApplyIf[test, f]]
is extremely common, I find.