Expand dataframe with vector

71 views Asked by At

Assume I have a dataframe a and a vector y

a = DataFrame(t = [0; 0], x = [1, 2])
y = [0.1, 0.2, 0.3]

how can I combine these two to achieve something like the following, preferentially using DataFramesMeta.jl?

 Row │ t        x     
     │ Float64  Int64 
─────┼────────────────
   1 │     0.1      1
   2 │     0.2      1
   3 │     0.3      1
   4 │     0.1      2
   5 │     0.2      2
   6 │     0.3      2

Edit: I prefer to use DataFramesMeta.jl because I like to use it in a @chain pipe.

2

There are 2 answers

1
BallpointBen On

You don't really need DataFramesMeta; a simple join will do. By creating two t columns with just a single distinct element, a join becomes the cartesian product.

julia> a = DataFrame(t = [0; 0], x = [1, 2])
2×2 DataFrame
 Row │ t      x     
     │ Int64  Int64 
─────┼──────────────
   1 │     0      1
   2 │     0      2

julia> b = DataFrame(t = 0, y = y)
3×2 DataFrame
 Row │ t      y       
     │ Int64  Float64 
─────┼────────────────
   1 │     0      0.1
   2 │     0      0.2
   3 │     0      0.3

julia> select(leftjoin(b, a, on=:t), :y => :t, :x)
6×2 DataFrame
 Row │ t        x      
     │ Float64  Int64? 
─────┼─────────────────
   1 │     0.1       1
   2 │     0.2       1
   3 │     0.3       1
   4 │     0.1       2
   5 │     0.2       2
   6 │     0.3       2

0
Dan Getz On

Maybe you are looking for:


julia> @combine(a,:t = repeat(y,length(:t)),
                  :x = repeat(:x; inner=length(y)))
6×2 DataFrame
 Row │ t        x     
     │ Float64  Int64 
─────┼────────────────
   1 │     0.1      1
   2 │     0.2      1
   3 │     0.3      1
   4 │     0.1      2
   5 │     0.2      2
   6 │     0.3      2

This can be generalized as needed to other cases. The crucial bit is that @combine takes multiple rows and can return more rows or fewer rows, unlike @select/@transform which maintain number of rows.