Given time series data as follows:

data = 
  {{{2011, 1, 13}, 10}, {{2011, 2, 14}, 17}, {{2011, 3, 15}, 20}, 
   {{2012, 1, 16}, 30}, {{2012, 2, 17}, 40}};


Cases[data, {{year_, month_, day_}, val_} /; year == 2011] 

will return the data that are in year 2011.

Are there any ways that I can define a function that can change the criteria of matching patterns?

For example,

TimeSelection[data_, pattern_] := Cases[data, {{year_, month_, day_}, val_} /; pattern]  

If the pattern is month == 2, the return will only be the data in February.


1 Answer 1


Your function would/should work, except for the fact that automatic renaming is taking place due to nested scoping constructs (here SetDelayed and Condition). Essentially Mathematica is trying to prevent a name collision, but that (shared names) is exactly what you need here. You can see the problem using Trace:

TimeSelection[{"anything"}, month == 2] // Trace

Note that the pattern name month has been renamed to month$. One simple work-around therefore is to use month$ in your condition:

TimeSelection[data, month$ == 2]
{{{2011, 2, 14}, 17}, {{2012, 2, 17}, 40}}

Another, more robust method, is to assemble the Condition expression at evaluation so your Pattern names do not explicitly appear inside that head as visible to SetDelayed:

TimeSelection[data_, pattern_] := 
  Cases[data, # /; pattern] & @ {{year_, month_, day_}, val_}

TimeSelection[data, month == 2]
{{{2011, 2, 14}, 17}, {{2012, 2, 17}, 40}}

The mechanism of this and other work-arounds is discussed in the post linked at the top of this answer. (Function with Slot does not suffer from automatic renaming, but Function with named parameters does.)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.