I figured out the same solution while Dason was answering mine.
I realized that dcast
simply does not know how to deal with duplicates. The way I figured out how to trick it was by adding another unique identifer so it doesn't get confused by duplicates.
In this example:
df <- ddply(df2, .(cat), function(x){ x$id2 = 1:nrow(x); x})
> dcast(df, id+id2~cat, value.var="val")[,-2]
id SS SV
1 A 220 224
2 B 222 225
3 C 223 220
4 C NA 1