Count and summarise ID's each day while creating a new column that shows the accumulated ID's
This is a base solution for your problem:

aggregate(paste(ID , Date) ~ ID + Date, data = df, FUN = length)


there are many more solutions like any of the ones below, using dplyr:

library(dplyr)
df %&gt;%  group_by(ID, Date) %&gt;% summarise(PurchaseCount = n())
df %&gt;% group_by(ID, Date) %&gt;% tally(name="PurchaseCount")
df %&gt;% group_by(ID, Date) %&gt;% count(name="PurchaseCount")
df %&gt;% group_by(ID, Date) %&gt;% add_tally(name="PurchaseCount")
df %&gt;% group_by(ID, Date) %&gt;% add_count(name="PurchaseCount")


or by using data.table package:

library(data.table)
setDT(df)[, PurchaseCount:=.N, by = list(ID, Date)]


or using sqldf package:

library(sqldf)
sqldf("SELECT ID, Date, COUNT(*) as PurchaseCount
       FROM df
       GROUP BY Date, ID")


or plyr:

plyr::count(df, c('ID','Date'))


I personally prefer data.table as it is directly writes to the dataframe and often is time efficient. aggregate is also favorable when you wanna avoid loading new libraries. dplyr generally make your code more legible as it uses pipingpersonal opinion.