1
$\begingroup$

I'm stuck with yet another list question. The basic gist: I have lists within a list like so:

list = {{"Joe", "Engineer",  Mon 2 Oct 2017}, {"Joe", "Activist", Wed 3 Oct 2017}, {"Joe", "Doctor", Wed 18 Oct 2017}};

What I would like to do is return anything in the list where the date (third element in each nested list) is greater than 2 weeks after the date of the previous list (Mon 2 Oct 2017). As a result, I would obtain the list:

{"Joe", "Doctor", Wed 18 Oct 2017}

Because {"Joe","Activist", Wed 3 Oct 2017} is not 2 weeks after the previous list, {"Joe", "Engineer", Mon 2 Oct 2017}, but {"Joe", "Doctor", Wed 3 Oct 2017} is

I have written out a logical script to test whether the date of a list immediately after the first is after two weeks:

list1=list[[1]];
DatePlus[list1[[3]], 14] < Flatten[list[[Flatten[Position[list, list1]] + 1]]][[3]]

This returns False, indicating that the date in the second list is not 2 weeks greater than the date in the first list

Another check:

list2 = list[[2]];
DatePlus[list2[[3]], 14] < Flatten[list[[Flatten[Position[list, list2]] + 1]]][[3]]

This returns True, indicating that the date in the third list is greater than two weeks of the date of the second list.

My goal is to basically iterate this process throughout the entire list without having to do individual checks, and then to return the lists where the date-element is 2 two weeks greater than the date-element of its previous list. I imagine I would have to use the If function, but am not sure how to iterate this process first.

Any help would be greatly appreciated!

$\endgroup$

2 Answers 2

3
$\begingroup$

Here is your list, where I added strings to the dates so that Mathematica will understand that they are dates:

list={{"Joe","Engineer","Mon 2 Oct 2017"},{"Joe","Activist","Wed 3 Oct 2017"},{"Joe","Doctor","Wed 18 Oct 2017"}};

I would convert your string dates into AbsoluteTime, and then take the differences:

diff = Differences[AbsoluteTime /@ list[[All,3]]]

{86400, 1296000}

Now, we need to determine which differences are bigger than 2 weeks:

biweek = QuantityMagnitude[Quantity[2, "Weeks"], "Seconds"]
clip = Clip[diff, {biweek, biweek-1}, {0, 1}]

1209600

{0, 1}

Finally, we pick the elements from the Rest of your list that correspond to 1:

Pick[
    Rest @ list,
    clip,
    1
]

{{"Joe", "Doctor", "Wed 18 Oct 2017"}}

Addendum

The reason I use AbsoluteTiming instead of working with date lists is speed. Consider:

abs = Sort @ RandomInteger[3*^9, 10000];
dl = DateList /@ abs;

Here, abs is a list of absolute times, and dl is a list of date lists. Now, compare:

Subtract @@@ Partition[abs, 2, 1]; //AbsoluteTiming
DayCount @@@ Partition[dl, 2, 1];//AbsoluteTiming

{0.004974, Null}

{4.76785, Null}

$\endgroup$
1
  • $\begingroup$ This worked like a charm, thank you very much! Never would have thought converting into AbsoluteTime would make things a lot simpler :) $\endgroup$ Oct 17, 2017 at 16:57
1
$\begingroup$
Pick[Rest @ #,  DayCount[##] > 14 & @@@ Partition[#[[All, 3]], 2, 1]] & @ list

{{"Joe", "Doctor", "Wed 18 Oct 2017"}}

$\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.