Using fill the way you do creates aliases:
julia> x = fill([], 2)
2-element Vector{Vector{Any}}:
[]
[]
julia> x[1] === x[2]
true
The simplest way to avoid the problem is to remove copycols=false in your code and all will be OK. DataFrame constructor copies data by default to avoid problems like you encountered.
Now an approach to avoid aliases in the first place could be the following. The simplest is to use a matrix constructor:
df_dash_table = DataFrame(fill(Float64, 0, length(dash_columns)-1), dash_columns[2:end])
another approach would be to use a comprehension:
df_dash_table = DataFrame([Float64[] for _ in 1:length(dash_columns)-1], dash_columns[2:end])
finally you could do:
df_dash_table = DataFrame([col => (col == "sym" ? String : Float64)[] for col in dash_columns])
to create a whole data frame in one shot.