Calling DataFrame(v)
should work.
If you have this scenario
julia> vnt = [(a = 1, b = (c = 2, d = 3)), (a = 4, b = (c = 5, d = 6))]
2-element Vector{NamedTuple{(:a, :b), Tuple{Int64, NamedTuple{(:c, :d), Tuple{Int64, Int64}}}}}:
(a = 1, b = (c = 2, d = 3))
(a = 4, b = (c = 5, d = 6))
then I’m not 100% what the solution is, but I’m sure other people can help out. Here is one solution with recursion
julia> vnt = [(a = 1, b = (c = 2, d = 3)), (a = 4, b = (c = 5, d = 6))];
julia> function unnest!(d, nt)
for (n, v) in pairs(nt)
if v isa NamedTuple
unnest!(d, v)
else
push!(d, n => v)
end
end
end;
julia> function unnest(nt)
d = Dict{Symbol, Any}()
unnest!(d, nt)
return d
end;
julia> Tables.istable(unnest.(vnt))
true
julia> DataFrame(unnest.(vnt))
2×3 DataFrame
Row │ a d c
│ Int64 Int64 Int64
─────┼─────────────────────
1 │ 1 3 2
2 │ 4 6 5
But this solution has some problems. In particular, it won’t have consistent column ordering (this can be fixed using an ordered dict from OrderedCollections.jl
).
But I feel like we have good solutions to this problem that I am not finding at the moment.
EDIT: Also look at JSONTables.jl, for a particular JSON-oriented use-case