Manipulating Panel Data in Julia

julia> using DataFrames, ShiftedArrays

julia> df = DataFrame(stock = ["a", "a", "a", "b", "b", "b"], time = repeat(1:3, 2), price = rand(100:120, 6))
6×3 DataFrame
 Row │ stock   time   price
     │ String  Int64  Int64
─────┼──────────────────────
   1 │ a           1    108
   2 │ a           2    105
   3 │ a           3    107
   4 │ b           1    101
   5 │ b           2    106
   6 │ b           3    109

julia> transform!(groupby(df, :stock), :price => (x -> log.(x) .- log.(lag(x))) => :return)
6×4 DataFrame
 Row │ stock   time   price  return
     │ String  Int64  Int64  Float64?
─────┼───────────────────────────────────────
   1 │ a           1    108  missing
   2 │ a           2    105       -0.0281709
   3 │ a           3    107        0.0188685
   4 │ b           1    101  missing
   5 │ b           2    106        0.0483186
   6 │ b           3    109        0.0279088
2 Likes