4
$\begingroup$

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

$\endgroup$
1
  • 1
    $\begingroup$ 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? $\endgroup$
    – kglr
    Oct 3 at 21:25

2 Answers 2

3
$\begingroup$

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

enter image description here

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 *)

enter image description here

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

True

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

enter image description here

$\endgroup$
3
$\begingroup$

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

enter image description here

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}

$\endgroup$

Your Answer

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

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