# DateSelect : columnwise selection applied to a matrix

Let consider :

• A time interval (January given by Time)
• A random set of values (Minimal example values given by Val)

as

Time = Map[DateObject, DateRange[{2022, 1, 1}, {2022, 1, 31}]];
Val = RandomReal[{0, 1}, Length@Time];


If I would like to extract some data between two days of January, this can be done by using

DateSelect[Time, 20 > #Day > 1 &]
(*{{2022, 1, 2, 0, 0, 0.}, {2022, 1, 3, 0, 0, 0.}, {2022, 1, 4, 0, 0, 0.}, {2022, 1, 5, 0, 0, 0.}, {2022, 1, 6, 0, 0, 0.}, {2022, 1, 7, 0, 0, 0.}, {2022, 1, 8, 0, 0, 0.}, {2022, 1, 9, 0, 0, 0.}, {2022, 1, 10, 0, 0, 0.}, {2022, 1, 11, 0, 0, 0.}, {2022, 1, 12, 0, 0, 0.}, {2022, 1, 13, 0, 0, 0.}, {2022, 1, 14, 0, 0, 0.}, {2022, 1, 15,0, 0, 0.}, {2022, 1, 16, 0, 0, 0.}, {2022, 1, 17, 0, 0, 0.}, {2022,1, 18, 0, 0, 0.}, {2022, 1, 19, 0, 0, 0.}}*)


Now let consider the following new dataset given by

Data = Transpose@{Time, Val};


I would like to extract some data with the function DateSelect but based on the first column of Data. For now I've tried :

• DateSelect[Data, 20 > #Day > 1 &] Failed
• DateSelect[Data, 20 > #[[1]] > 1 &] Failed
• DateSelect[Data, 20 > #Day[[1]] > 1 &] Failed

A possibility would be (but less elegant in my opinion)

Select[Data, 20 > DateValue[#[[1]], "Day"] > 1 &]


Any idea to restrict to DateSelect

• DateSelect takes only a list of date objects (DateObject, DateInterval,DateList, DateString) as the first argument.So you cannot use DateSelect[Data, pred] for any pred to get the filtering you want. Perhaps you might find something like Select[Data, 20 > #[[1]]["Day"] > 1 &] less inelegant?
– kglr
Oct 3 at 21:25

As the error message from execution of DateSelect[Data, True &] indicates

you can only use "a list of recognized date specifications or a date interval" (DateObject, DateInterval, DateList, DateString) as the first argument in DateSelect.

Some alternatives to get the desired filtering are:

Select[20 > #[[1]]["Day"] > 1 &] @ Data

(* or Select[20 > #["Day"] > 1 & @* First] @ Data *)


Cases[{_?(20 > #["Day"] > 1 &), _}] @ Data == %


True

Select[#[[1]]["DayNameShort"] == "Wed" &] @ Data


You could transform your data into an Association:

time = Map[DateObject, DateRange[{2022, 1, 1}, {2022, 1, 31}]];
val = RandomReal[{0, 1}, Length @ time];

data = AssociationThread[time -> val];


Now you can use Lookup and DateSelect to get the values between two dates:

Lookup[data, DateSelect[time, Between[#Day, {3, 6}] &]]


{0.153392, 0.0392318, 0.127469, 0.526201}

If you also want to see the dates use KeyTake:

KeyTake[DateSelect[time, Between[#Day, {3, 6}] &]] @ data // Dataset


If you want to do this repeatedly, define your own little function to save some keystrokes:

ds[a_, b_] := DateSelect[a, Between[#Day, b] &]

Lookup[data, ds[time, {20, 21}]]


{0.94804, 0.0967288}