The shortest solution is probably using the rowid
function from the data.table package:
library(data.table)
dt <- dcast(setDT(df), rowid(left) ~ left, value.var = "right")
dt[, names(dt)[1] := NULL]
which gives:
> dt
a b c d
1: 18 52 67 12
2: 36 74 61 86
3: 81 41 82 3