sqldf For complex joins, it is usually easier to use SQL:
library(sqldf) sqldf("select id, year, month, wday.weekday, sum((df.weekday = wday.weekday) * amount) amount from df join wday group by 1, 2, 3, 4")
giving:
id year month weekday amount 1 1 2015 1 Friday 3650.43 2 1 2015 1 Saturday 0.00 3 1 2015 1 Wednesday 0.00 4 1 2015 1 Sunday 0.00 5 1 2015 1 Tuesday 0.00 6 1 2015 1 Monday 0.00 7 1 2015 1 Thursday 0.00 8 2 2015 1 Friday 0.00 9 2 2015 1 Saturday 0.00 10 2 2015 1 Wednesday 0.00 11 2 2015 1 Sunday 0.00 12 2 2015 1 Tuesday 0.00 13 2 2015 1 Monday 1271.12 14 2 2015 1 Thursday 0.00 15 1 2015 2 Friday 1315.79 16 1 2015 2 Saturday 0.00 17 1 2015 2 Wednesday 0.00 18 1 2015 2 Sunday 0.00 19 1 2015 2 Tuesday 0.00 20 1 2015 2 Monday 0.00 21 1 2015 2 Thursday 0.00 22 2 2015 2 Friday 0.00 23 2 2015 2 Saturday 0.00 24 2 2015 2 Wednesday 0.00 25 2 2015 2 Sunday 0.00 26 2 2015 2 Tuesday 0.00 27 2 2015 2 Monday 2195.37 28 2 2015 2 Thursday 0.00
base R We could replicate this in base R using merge and transform :
xt <- transform( merge(df, wday, by = c()), amount = (as.character(weekday.x) == as.character(weekday.y)) * amount, weekday = weekday.y, weekday.x = NULL, weekday.y = NULL )) aggregate(amount ~., xt, sum)
dplyr , and if we really wanted to use dplyr, we could replace transform with mutate , rename and select :
library(dplyr) merge(df, wday, by = c()) %>% mutate(amount = (as.character(weekday.x) == as.character(weekday.y)) * amount) %>% rename(weekday = weekday.y) %>% select(-weekday.x) %>% group_by(id, year, month, weekday) %>% summarise(amount = sum(amount))
Note. If each group has only one day of the week (as in the question), we could optionally omit the group by / sum, aggregate, and group_by / summary in three solutions, respectively.