Programmatically adding multiple colums to a dataframe

Suppose I have the following code:

n = ["a_" * string(i) for i in 1:3]
v = [1,2,3]
df = DataFrame(a = [1, 2], b = [3, 4])
df_new = @chain df begin
    @transform $(n[1]) = v[1]
end

Can I change the @transform to add 3 new columns such that the result looks like

2×5 DataFrame
 Row │ a      b      a_1    a_2    a_3   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      2      3
   2 │     2      4      1      2      3

Thanks!

In vanilla DataFrames.jl the simplest way to do it is:

julia> insertcols(df,  ["a_$i" => i for i in 1:3]...)
2×5 DataFrame
 Row │ a      b      a_1    a_2    a_3
     │ Int64  Int64  Int64  Int64  Int64
─────┼───────────────────────────────────
   1 │     1      3      1      2      3
   2 │     2      4      1      2      3
3 Likes

Great questions. All the syntaxes within a chain block seem a bit clunky


julia> @chain df begin
           copy
           begin 
               for (ni, vi) in zip(n, v)
                   @rtransform! _ $ni = $vi
               end
               _
           end
       end
2×5 DataFrame
 Row │ a      b      a_1    a_2    a_3   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      3      1
   2 │     2      4      2      4      2

You can also leverage AsTable as follows

julia> @chain df begin
           @rtransform $AsTable = (; (Symbol(n[i]) => v[i] for i in eachindex(n))...)
       end
2×5 DataFrame
 Row │ a      b      a_1    a_2    a_3   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      2      3
   2 │     2      4      1      2      3

This is also very ugly. It looks like you can simplify things by using a Dict, though the order of columns might not be consistent, and performance will be hurt a little

julia> @chain df begin
           @rtransform $AsTable = Dict(n[i] => v[i] for i in eachindex(n))
       end
2×5 DataFrame
 Row │ a      b      a_1    a_2    a_3   
     │ Int64  Int64  Int64  Int64  Int64 
─────┼───────────────────────────────────
   1 │     1      3      1      2      3
   2 │     2      4      1      2      3

Thanks a lot, also to @bkamins. There’s a lot I can work with!

in decreasing order of weirdness

transform(df,Cols(:)=>((x...)->(;(n .=> v) ...))=>AsTable)
transform(df,:a=>((x)->(;(n .=> v) ...))=>AsTable)

insertcols(df,  ["a_$i" => v[i] for i in 1:3]...)
insertcols(df,  (n .=> v) ...)
DataFrame(pairs(eachcol(df))...,(n.=>v)...)