# Count items in a list that occur before a date

I have a list of dates that happen throughout 2013. I wish to construct a graph showing a cumulative total of elements that happen before that date.

I have a working algorithm, but it seems too slow and inefficient.

Let's generate some random dates:

dates = {2013, #[[1]], #[[2]]} & /@ Transpose@{RandomInteger[{1, 12}, {100}],
RandomInteger[{1, 30}, {100}]};


Define a function that calculates the totals:

datecounts[dates_, effectivedate_, spanindays_] := Module[{range, compares},
range = DateRange[effectivedate, DatePlus[effectivedate, spanindays]];
compares = Partition[(AbsoluteTime[#[[1]]] > AbsoluteTime[#[[2]]]) & /@
Tuples[{range, dates}], Length[dates]];
Transpose@{range, Count[#, True] & /@ compares}]


And graph the results:

DateListPlot[datecounts[dates, {2013, 1, 1}, 365], PlotStyle -> {Thickness[0.003]},
Joined -> True, GridLines -> Automatic, FrameLabel -> {Null, "Total Count"}]


Any help in improving efficiency or better use of functions is greatly appreciated.

• Do you really need to plot every day's value? You could try InterpolationOrder -> 0 to get your nice flat lines. Feb 1, 2013 at 4:55
• @Verbeia Great point. I'll delete that update.
– kale
Feb 1, 2013 at 4:56

newdata =  Transpose[{dates[[Ordering[AbsoluteTime /@ dates]]], Range@Length@dates}];
DateListPlot[newdata, Joined -> True]


 DateListPlot[newdata,Joined -> True, InterpolationOrder -> 0]


Update: Let HistogramList do the counting:

 dts = AbsoluteTime /@ dates;
(* number of says between the earliest and latest dates -
to be used as the number of bins in the second argument of HistogramList*)
daysbetween = DateDifference[Sequence @@ Through[{Min, Max}[dts]]];
DateListPlot[Transpose[Delete[
HistogramList[dts, daysbetween, "CumulativeCount"],
{1, 1}]],
Joined -> True, ImageSize -> 500]


Update 2: ... there is also EmpiricalDistribution

  {min, max} = Through[{Min, Max}[dts]];
Plot[CDF[EmpiricalDistribution[dts], x], {x, min, max}]

• You get my +1 for HistogramList. Feb 1, 2013 at 13:47

Since you are just looking for counts, I would do the following:

DateListPlot[
Transpose[{
AbsoluteTime /@ Sort[#, AbsoluteTime[#1] < AbsoluteTime[#2]& ]& @ dates,
Range @ Length @ dates
}],
PlotStyle -> {Thickness[0.003]}, Joined -> True,
GridLines -> Automatic, FrameLabel -> {Null, "Total Count"},
InterpolationOrder -> 0
]


• Much faster, but only plots 100 points in this case instead of a point for each day in 2013... Not a bad thing, just haven't thought of it that way.
– kale
Feb 1, 2013 at 4:34

You could use that:

plotDates[dates_,dtIni_,years_:1]:=Module[{newDate},
newDate=Tally[Sort@dates];
newDate[[All,2]]=Accumulate[newDate[[All,2]]];
DateListPlot[newDate,Joined->True,PlotStyle->{Thick,Red},InterpolationOrder->0,PlotRange->{{dtIni,DatePlus[dtIni,{years,"Year"}]},All}]
]


I like this ways to accumulate the informations, it's very fast!

plotDates[dates,{2013,1,1}]