1
$\begingroup$

I can use Select to extract rows with specific dates from my dataset, but I'd like to instead select all rows that fall within a date interval. From the documentation, it appears that IntervalMemberQ applied to DateInterval should work, but I've not had success:

Note that the syntax for IntervalMemberQ is reversed from MemberQ, and is thus IntervalMemberQ[di,#] rather than IntervalMemberQ[#,di].

dataset = {{DateObject[{2020, 1, 1, 0, 0, 0}], "stuffA", 10, 
        100}, {DateObject[{2020, 1, 1, 1, 0, 0}], "stuffB", 20, 
        200}, {DateObject[{2020, 1, 1, 2, 0, 0}], "stuffC", 30, 300}}; 

do1 = DateObject[{2020, 1, 1, 0, 0, 0}]
do2 = DateObject[{2020, 1, 1, 1, 0, 0}]
Select[dataset, MemberQ[#, do1] &]
Select[dataset, MemberQ[#, do2] &]
di = DateInterval[{do1, do2}]
Select[dataset, IntervalMemberQ[di,#] &]

enter image description here

$\endgroup$
2
  • $\begingroup$ try di = DateInterval[First/@{do1, do2}];Select[dataset, IntervalMemberQ[di,First@#] &]? $\endgroup$
    – kglr
    Commented May 2, 2021 at 9:42
  • 1
    $\begingroup$ Thanks @klgr. Please see my answer. $\endgroup$
    – theorist
    Commented May 2, 2021 at 10:16

1 Answer 1

1
$\begingroup$

There are two problems that need to be overcome.

The first is this:

MemberQ will return True if any of the elements in the row correspond to the specified date

MemberQ[dataset[[1]], do1]

True

However, IntervalMemberQ evaluates all the elements in the row, and thus returns:

IntervalMemberQ[di, dataset[[1]]]

{True, False, False, False}

Since the date values are in the first column, I need to select the first element of IntervalMemberQ's output:

IntervalMemberQ[di, dataset[[1]]]

True

Thus the expected solution is:

Select[dataset, IntervalMemberQ[di, #][[1]] &]

However this reveals the second problem, which is that IntervalMemberQ drops the last date:

enter image description here

To address this, it is necessary to specify an end date that is just beyond the desired end date:

do3 = DateObject[{2020, 1, 1, 2, 0, 0}]
di3 = DateInterval[{do1, do3}]
Select[dataset, IntervalMemberQ[di3, #][[1]] &]

enter image description here

I.e., IntervalMemberQ selects dates such that:

interval start date <= date < interval end date

$\endgroup$

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.