I have a list of date & value pairs. There can be multiple entries for each day. Sample data can be generated with the following:
maxDays = 10;
date = AbsoluteTime[{2013, 5, 13}];
dateValuePairs = Flatten[Table[{date + day * 86400, value}, {day, maxDays}, {value, 10}], 1];
The sample data looks like:
{{3577478400, 1}, {3577478400, 2}, ... {3577478400, 10},
{3577564800, 1}, {3577564800, 2}, ... {3577564800, 10},
...
{3578256000, 1}, {3578256000, 2}, ... {3578256000, 10}}
I am trying to sum the values for the same day. With the sample data above, I expected to see ten days, each with a value of 55 .
I tried the following:
Clear[sumByDay];
Map[
(sumByDay[#[[1]]] =
If[ValueQ[sumByDay[#[[1]]]],
sumByDay[#[[1]]] + #[[2]],
#[[2]]
]) &, dateValuePairs];
DownValues[sumByDay]
... and I expected it to return:
Out[]= {HoldPattern[sumByDay[3577478400]] :> 55, HoldPattern[sumByDay[3577564800]] :> 55, ... HoldPattern[sumByDay[3578256000]] :> 55}
... however I receive:
$RecursionLimit::reclim: Recursion depth of 256 exceeded. >>
Out[]= {HoldPattern[sumByDay[3577478400]] :> 1 + sumByDay[3577478400]}
sumByDay[#[[1]]] + #[[2]]
must not be being evaluated as I expected, see below:
In[]:= a[3577478400] = 1
In[]:= a[3577478400] = a[3577478400] + 2
...
In[]:= a[3577478400] = a[3577478400] + 10
Out[]= 1
Out[]= 3
...
Out[]= 55
And the Question of Efficiency ...
I am sure I can accomplish this less efficiently. As I am equally sure that it can be done more efficiently. i.e. :
Map[(day = #;
{day, Total[
Transpose[Select[dateValuePairs, #[[1]] == day &]][[2]]]}
) &, Sort[DeleteDuplicates[Transpose[dateValuePairs][[1]]]]]
The number of days defined by maxDays
in the sample data example will grow at a const rate.
GatherBy
as in{#[[1, 1]], Total[#[[All, 2]]]} & /@ GatherBy[dateValuePairs, #[[1]] &]
. $\endgroup$Gather
andGatherBy
(and look through the results for one that matches) $\endgroup$Gather
&GatherBy
... that is what I was missing. $\endgroup$DownValues
? $\endgroup$