This gives you a different row order, but I assume this is acceptable (you can always re-order later):
dv2 = df.dv2;
df2 = select(df, Not(:dv2));
for (i, v) in enumerate(dv2)
if v isa Number
push!(df2, (df2.id[i], df2.time[i], v, 3))
end
end
Note that your data does not have missing values but a mixture of '.' and "." for non-numeric data so I did v isa Number check. You might want to use some other test in your production code.