I would like to apply one of two possible functions to a column of a DataFrame, based on its category (one for each function) which is specified in another column.
The use case I have for this is converting the JD times of a list of observations from two separate locations to BJD (Barycentric Julian Date), which is dependent on that location.
For example, if I had a table like:
julia> using DataFrames
julia> df = DataFrame(:t => 1:5, :location => rand(["locA", "locB"], 5))
5×2 DataFrame
Row │ t location
│ Int64 String
─────┼─────────────────
1 │ 1 locB
2 │ 2 locA
3 │ 3 locA
4 │ 4 locB
5 │ 5 locA
where the BJD time at locA = t^2 and the time at locB = -t^2 (just for clarity), how could I add this new column?
One way I have tried is to just apply a ternary function:
julia> loc_to_BJD(t, loc) = loc == "locA" ? t^2 : -t^2
loc_to_BJD (generic function with 1 method)
julia> df.loc_to_BJD = loc_to_BJD.(df.t, df.location); df
5×3 DataFrame
Row │ t location loc_to_BJD
│ Int64 String Int64
─────┼─────────────────────────────
1 │ 1 locB -1
2 │ 2 locA 4
3 │ 3 locA 9
4 │ 4 locB -16
5 │ 5 locA 25
but running a check on the category each time like this seems awfully inefficient (unless the compiler is doing something clever behind the scenes?)
Would using groups make more sense in this case? I run into the problem of trying to add a column to a SubDataFrame when trying this though, so I do not think that I am approaching this from the right direction.