DataFrame to Dict via Vector of Nested Named Tuples

I am building a JuMP transportation model, and looking for an alternate approach to create a dict from a dataframe. Here is my starting (simplified) DataFrame:

using DataFrames
using NamedTupleTools
df = DataFrame(City=["Boston", "Dallas", "Chicago"], State=["MA", "TX", "IL"], Part = [:X, :Y, :Z])

3×3 DataFrame
 Row │ City     State   Part   
     │ String   String  Symbol 
─────┼─────────────────────────
   1 │ Boston   MA      X      
   2 │ Dallas   TX      Y      
   3 │ Chicago  IL      Z  

And I create this vector of struct (to serve as the key for a dict of customer demand data):

3-element Vector{Demand}:
 Demand(Loc("Boston", "MA"), :X)
 Demand(Loc("Dallas", "TX"), :Y)
 Demand(Loc("Chicago", "IL"), :Z)

Via these steps:

struct Loc
    City::String
    State::String
end

# Loc as a named tuple
loc_nt = Tables.rowtable(DataFrames.select(df, :City, :State))
# convert to a structure
loc = structfromnt.(Loc, loc_nt)

struct Demand
    Dest::Loc
    Part::Symbol
end

dmd_st = Demand[]
for i in 1 : nrow(df)
    push!(dmd_st, Demand(loc[i], df.Part[i]))
end

My question: is there a better way to do this, perhaps using nested named tuples and converting them to the struc? Coming from R, it’s hard to get used to loops. I want to keep the nested struct to simplify some constraints.

Thanks for any suggestions.

1 Like

I would just do:

julia> Demand.(Loc.(df.City, df.State), df.Part)
3-element Vector{Demand}:
 Demand(Loc("Boston", "MA"), :X)
 Demand(Loc("Dallas", "TX"), :Y)
 Demand(Loc("Chicago", "IL"), :Z)

and since you are coming from R an alternative is:

julia> using DataFramesMeta

julia> @with(df, Demand.(Loc.(:City, :State), :Part))
3-element Vector{Demand}:
 Demand(Loc("Boston", "MA"), :X)
 Demand(Loc("Dallas", "TX"), :Y)
 Demand(Loc("Chicago", "IL"), :Z)
1 Like

Fantastic! I knew I was overcomplicating it. Thank you so much.

1 Like