as.data.frame(lapply(split.default(df, names(df)), function(x) Reduce(`+`, x)))
produces:
v1 v2
1 3 5
2 5 1
split.default(...)
breaks up the data frame into groups with equal column names, then we use Reduce
on each of those groups to sum the values of each column in the group iteratively until there is only one column left per group (see ?Reduce
, that is what the function does), and finally we convert back to data frame with as.data.frame
.
We have to use split.default
because split
(or really, split.data.frame
, which it will dispatch) splits on rows, not columns.