I think this technique is interesting. Perhaps if someone can edit the to_named_tuple
piece this could work:
using DataFrames, NamedTuples
#gentup(struct_T) = NamedTuple{( fieldnames(struct_T)...,),
# Tuple{(fieldtype(struct_T,i) for i=1:fieldcount(struct_T))...}}
#
#@generated function to_named_tuple_generated(x)
# nt = Expr(:quote, gentup(x))
# tup = Expr(:tuple)
# for i=1:fieldcount(x)
# push!(tup.args, :(getfield(x, $i)) )
# end
# return :($nt($tup))
#end
#
#
#to_named_tuple_naive(p) = (; (v=>getfield(p, v) for v in fieldnames(typeof(p)))...)
mutable struct Person
age::Int64
id::Int64
name::String
weight::Float64
blood_type::String
average_resting_heart_rate::Int64
IQ::Int64
end
function update!(person::Person)
person.age += 1
person.weight += rand() - 0.5
end
function logging_df(a_struct)
DataFrame(prepend!(map(x -> fieldtype(a_struct, x),
fieldnames(a_struct)
),
[Int64]
),
prepend!(fieldnames(a_struct),
[:timestep]
),
0)
end
p = Person(18, 123, "foo", 72.5, "AB", 66, 100);
function log!(simresults, t, p)
push!(simresults, prepend!(to_named_tuple(p),[t]))
end
all_people = [p]
function run_simulation!(timesteps::Int64, all_people, simresults)
for t in 1:timesteps
map(update!,all_people)
log!(simresults,t,all_people)
end
end
simresults = logging_df(Person)
run_simulation!(10,all_people,simresults)
simresults