Define
# WARNING: `parsedf` parses/evaluates input text and
# is therefore an infosec weakness. Should be used only
# with properly vetted input.
parsedf(df) = DataFrame([c=>eval.(Meta.parse.(df[:,c]))
for c in names(df)])
spreaddf(df) = DataFrame([c*"$i" => get.(df[:, c],i,missing)
for (c, i) in vcat([[(names(df)[i],j)
for j=1:L]
for (i,L) in enumerate([maximum(length.(df[:,i]))
for i in 1:ncol(df)])]...)]...)
Now,
julia> df = DataFrame(A=["[1,2]"],B=["[3,4]"])
1×2 DataFrame
Row │ A B
│ String String
─────┼────────────────
1 │ [1,2] [3,4]
julia> spreaddf(parsedf(df))
1×4 DataFrame
Row │ A1 A2 B1 B2
│ Int64 Int64 Int64 Int64
─────┼────────────────────────────
1 │ 1 2 3 4
seems to do it.
Also,
julia> spreaddf(parsedf(DataFrame(A=["[1,2]","[5,6]"], B=["[3,4]","[7,8,9]"])))
2×5 DataFrame
Row │ A1 A2 B1 B2 B3
│ Int64 Int64 Int64 Int64 Int64?
─────┼─────────────────────────────────────
1 │ 1 2 3 4 missing
2 │ 5 6 7 8 9
seems appropriate.