1. Find all flights that
(a) Had an arrival delay of two or more hours
Since the arr_delay
variable is measured in minutes, find flights with an arrival delay of 120 or more minutes.
filter(flights, arr_delay >= 120)
(b) Flew to Houston (IAH or HOU)
The flights that flew to Houston are those flights where the destination (dest
) is either “IAH” or “HOU”.
filter(flights, dest == "IAH" | dest == "HOU")
However, using %in%
is more compact and would scale to cases where there were more than two airports we were interested in.
filter(flights, dest %in% c("IAH", "HOU"))
(c) Were operated by United, American, or Delta
In the flights
dataset, the column carrier
indicates the airline, but it uses two-character carrier codes. We can find the carrier codes for the airlines in the airlines dataset. Since the carrier code dataset only has 16 rows, and the names of the airlines in that dataset are not exactly “United”, “American”, or “Delta”, it is easiest to manually look up their carrier codes in that data.
airlines
The carrier code for Delta is "DL"
, for American is "AA"
, and for United is "UA"
. Using these carriers codes, we check whether carrier
is one of those.
filter(flights, carrier %in% c("AA", "DL", "UA"))
(d) Departed in summer (July, August, and September)
The variable month
has the month, and it is numeric. So, the summer flights are those that departed in months 7 (July), 8 (August), and 9 (September).
filter(flights, month >= 7, month <= 9)
The %in%
operator is an alternative. If the :
operator is used to specify the integer range, the expression is readable and compact.
filter(flights, month %in% 7:9)
We could also use the |
operator. However, the |
does not scale to many choices. Even with only three choices, it is quite verbose.
filter(flights, month == 7 | month == 8 | month == 9)
(e) Arrived more than two hours late, but didn’t leave late
Flights that arrived more than two hours late, but didn’t leave late will have an arrival delay of more than 120 minutes (arr_delay > 120
) and a non-positive departure delay (dep_delay <= 0
).
filter(flights, arr_delay > 120, dep_delay <= 0)
(f) Were delayed by at least an hour, but made up over 30 minutes in flight
Were delayed by at least an hour, but made up over 30 minutes in flight. If a flight was delayed by at least an hour, then dep_delay >= 60
. If the flight didn’t make up any time in the air, then its arrival would be delayed by the same amount as its departure, meaning dep_delay == arr_delay
, or alternatively, dep_delay - arr_delay == 0
. If it makes up over 30 minutes in the air, then the arrival delay must be at least 30 minutes less than the departure delay, which is stated as dep_delay - arr_delay > 30
.
filter(flights, dep_delay >= 60, dep_delay - arr_delay > 30)
(g) Departed between midnight and 6 am (inclusive)
Finding flights that departed between midnight and 6 a.m. is complicated by the way in which times are represented in the data. In dep_time
, midnight is represented by 2400
, not 0
. You can verify this by checking the minimum and maximum of dep_time.
summary(flights$dep_time)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
1 907 1401 1349 1744 2400 8255
This is an example of why it is always good to check the summary statistics of your data. Unfortunately, this means we cannot simply check that dep_time < 600
, because we also have to consider the special case of midnight.
filter(flights, dep_time <= 600 | dep_time == 2400)
Alternatively, we could use the modulo operator, %%
. The modulo operator returns the remainder of division. Let’s see how how this affects our times.
c(600, 1200, 2400) %% 2400
[1] 600 1200 0
Since 2400 %% 2400 == 0
and all other times are left unchanged, we can compare the result of the modulo operation to 600
,
filter(flights, dep_time %% 2400 <= 600)
This filter expression is more compact, but its readability will depends on the familiarity of the reader with modular arithmetic.
2. Another useful dplyr filtering helper is between()
. What does it do? Can you use it to simplify the code needed to answer the previous challenges?
The expression between(x, left, right)
is equivalent to x >= left & x <= right
.
Of the answers in the previous question, we could simplify the statement of departed in summer (month >= 7 & month <= 9
) using the between()
function.
filter(flights, between(month, 7, 9))
LS0tDQp0aXRsZTogIkZpbHRlciByb3dzIHdpdGggZmlsdGVyKCkiDQpvdXRwdXQ6IA0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNA0KLS0tDQoNCg0KYGBge3IgbG9hZGxpYnJhcnl9DQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeShueWNmbGlnaHRzMTMpKQ0Kc3VwcHJlc3NQYWNrYWdlU3RhcnR1cE1lc3NhZ2VzKGxpYnJhcnkodGlkeXZlcnNlKSkNCmBgYA0KDQojIyMgMS4gRmluZCBhbGwgZmxpZ2h0cyB0aGF0DQoNCiMjIyMgKGEpIEhhZCBhbiBhcnJpdmFsIGRlbGF5IG9mIHR3byBvciBtb3JlIGhvdXJzDQoNClNpbmNlIHRoZSBgYXJyX2RlbGF5YCB2YXJpYWJsZSBpcyBtZWFzdXJlZCBpbiBtaW51dGVzLCBmaW5kIGZsaWdodHMgd2l0aCBhbiBhcnJpdmFsIGRlbGF5IG9mIDEyMCBvciBtb3JlIG1pbnV0ZXMuDQoNCmBgYHtyIGRlbGF5fQ0KZmlsdGVyKGZsaWdodHMsIGFycl9kZWxheSA+PSAxMjApDQpgYGANCg0KIyMjIyAoYikgRmxldyB0byBIb3VzdG9uIChJQUggb3IgSE9VKQ0KDQpUaGUgZmxpZ2h0cyB0aGF0IGZsZXcgdG8gSG91c3RvbiBhcmUgdGhvc2UgZmxpZ2h0cyB3aGVyZSB0aGUgZGVzdGluYXRpb24gKGBkZXN0YCkgaXMgZWl0aGVyIOKAnElBSOKAnSBvciDigJxIT1XigJ0uDQoNCmBgYHtyIGRlc3RIT1V9DQpmaWx0ZXIoZmxpZ2h0cywgZGVzdCA9PSAiSUFIIiB8IGRlc3QgPT0gIkhPVSIpDQpgYGANCg0KSG93ZXZlciwgdXNpbmcgYCVpbiVgIGlzIG1vcmUgY29tcGFjdCBhbmQgd291bGQgc2NhbGUgdG8gY2FzZXMgd2hlcmUgdGhlcmUgd2VyZSBtb3JlIHRoYW4gdHdvIGFpcnBvcnRzIHdlIHdlcmUgaW50ZXJlc3RlZCBpbi4NCg0KYGBge3IgaW59DQpmaWx0ZXIoZmxpZ2h0cywgZGVzdCAlaW4lIGMoIklBSCIsICJIT1UiKSkNCmBgYA0KDQojIyMjIChjKSBXZXJlIG9wZXJhdGVkIGJ5IFVuaXRlZCwgQW1lcmljYW4sIG9yIERlbHRhDQoNCkluIHRoZSBgZmxpZ2h0c2AgZGF0YXNldCwgdGhlIGNvbHVtbiBgY2FycmllcmAgaW5kaWNhdGVzIHRoZSBhaXJsaW5lLCBidXQgaXQgdXNlcyB0d28tY2hhcmFjdGVyIGNhcnJpZXIgY29kZXMuIFdlIGNhbiBmaW5kIHRoZSBjYXJyaWVyIGNvZGVzIGZvciB0aGUgYWlybGluZXMgaW4gdGhlIGFpcmxpbmVzIGRhdGFzZXQuIFNpbmNlIHRoZSBjYXJyaWVyIGNvZGUgZGF0YXNldCBvbmx5IGhhcyAxNiByb3dzLCBhbmQgdGhlIG5hbWVzIG9mIHRoZSBhaXJsaW5lcyBpbiB0aGF0IGRhdGFzZXQgYXJlIG5vdCBleGFjdGx5IOKAnFVuaXRlZOKAnSwg4oCcQW1lcmljYW7igJ0sIG9yIOKAnERlbHRh4oCdLCBpdCBpcyBlYXNpZXN0IHRvIG1hbnVhbGx5IGxvb2sgdXAgdGhlaXIgY2FycmllciBjb2RlcyBpbiB0aGF0IGRhdGEuDQoNCmBgYHtyIGFpcmxpbmVzfQ0KYWlybGluZXMNCmBgYA0KDQpUaGUgY2FycmllciBjb2RlIGZvciBEZWx0YSBpcyBgIkRMImAsIGZvciBBbWVyaWNhbiBpcyBgIkFBImAsIGFuZCBmb3IgVW5pdGVkIGlzIGAiVUEiYC4gVXNpbmcgdGhlc2UgY2FycmllcnMgY29kZXMsIHdlIGNoZWNrIHdoZXRoZXIgYGNhcnJpZXJgIGlzIG9uZSBvZiB0aG9zZS4NCg0KYGBge3J9DQpmaWx0ZXIoZmxpZ2h0cywgY2FycmllciAlaW4lIGMoIkFBIiwgIkRMIiwgIlVBIikpDQpgYGANCg0KIyMjIyAoZCkgRGVwYXJ0ZWQgaW4gc3VtbWVyIChKdWx5LCBBdWd1c3QsIGFuZCBTZXB0ZW1iZXIpDQoNClRoZSB2YXJpYWJsZSBgbW9udGhgIGhhcyB0aGUgbW9udGgsIGFuZCBpdCBpcyBudW1lcmljLiBTbywgdGhlIHN1bW1lciBmbGlnaHRzIGFyZSB0aG9zZSB0aGF0IGRlcGFydGVkIGluIG1vbnRocyA3IChKdWx5KSwgOCAoQXVndXN0KSwgYW5kIDkgKFNlcHRlbWJlcikuDQoNCmBgYHtyIG1vbnRofQ0KZmlsdGVyKGZsaWdodHMsIG1vbnRoID49IDcsIG1vbnRoIDw9IDkpDQpgYGANCg0KVGhlIGAlaW4lYCBvcGVyYXRvciBpcyBhbiBhbHRlcm5hdGl2ZS4gSWYgdGhlIGA6YCBvcGVyYXRvciBpcyB1c2VkIHRvIHNwZWNpZnkgdGhlIGludGVnZXIgcmFuZ2UsIHRoZSBleHByZXNzaW9uIGlzIHJlYWRhYmxlIGFuZCBjb21wYWN0Lg0KDQpgYGB7ciBpbmNvbG9ufQ0KZmlsdGVyKGZsaWdodHMsIG1vbnRoICVpbiUgNzo5KQ0KYGBgDQoNCldlIGNvdWxkIGFsc28gdXNlIHRoZSBgfGAgb3BlcmF0b3IuIEhvd2V2ZXIsIHRoZSBgfGAgZG9lcyBub3Qgc2NhbGUgdG8gbWFueSBjaG9pY2VzLiBFdmVuIHdpdGggb25seSB0aHJlZSBjaG9pY2VzLCBpdCBpcyBxdWl0ZSB2ZXJib3NlLg0KDQpgYGB7ciB2ZXJib3NlfQ0KZmlsdGVyKGZsaWdodHMsIG1vbnRoID09IDcgfCBtb250aCA9PSA4IHwgbW9udGggPT0gOSkNCmBgYA0KDQoNCiMjIyMgKGUpIEFycml2ZWQgbW9yZSB0aGFuIHR3byBob3VycyBsYXRlLCBidXQgZGlkbuKAmXQgbGVhdmUgbGF0ZQ0KDQpGbGlnaHRzIHRoYXQgYXJyaXZlZCBtb3JlIHRoYW4gdHdvIGhvdXJzIGxhdGUsIGJ1dCBkaWRu4oCZdCBsZWF2ZSBsYXRlIHdpbGwgaGF2ZSBhbiBhcnJpdmFsIGRlbGF5IG9mIG1vcmUgdGhhbiAxMjAgbWludXRlcyAoYGFycl9kZWxheSA+IDEyMGApIGFuZCBhIG5vbi1wb3NpdGl2ZSBkZXBhcnR1cmUgZGVsYXkgKGBkZXBfZGVsYXkgPD0gMGApLg0KDQpgYGB7ciBub2xlYXZlfQ0KZmlsdGVyKGZsaWdodHMsIGFycl9kZWxheSA+IDEyMCwgZGVwX2RlbGF5IDw9IDApDQpgYGANCg0KIyMjIyAoZikgV2VyZSBkZWxheWVkIGJ5IGF0IGxlYXN0IGFuIGhvdXIsIGJ1dCBtYWRlIHVwIG92ZXIgMzAgbWludXRlcyBpbiBmbGlnaHQNCg0KV2VyZSBkZWxheWVkIGJ5IGF0IGxlYXN0IGFuIGhvdXIsIGJ1dCBtYWRlIHVwIG92ZXIgMzAgbWludXRlcyBpbiBmbGlnaHQuIElmIGEgZmxpZ2h0IHdhcyBkZWxheWVkIGJ5IGF0IGxlYXN0IGFuIGhvdXIsIHRoZW4gYGRlcF9kZWxheSA+PSA2MGAuIElmIHRoZSBmbGlnaHQgZGlkbuKAmXQgbWFrZSB1cCBhbnkgdGltZSBpbiB0aGUgYWlyLCB0aGVuIGl0cyBhcnJpdmFsIHdvdWxkIGJlIGRlbGF5ZWQgYnkgdGhlIHNhbWUgYW1vdW50IGFzIGl0cyBkZXBhcnR1cmUsIG1lYW5pbmcgYGRlcF9kZWxheSA9PSBhcnJfZGVsYXlgLCBvciBhbHRlcm5hdGl2ZWx5LCBgZGVwX2RlbGF5IC0gYXJyX2RlbGF5ID09IDBgLiBJZiBpdCBtYWtlcyB1cCBvdmVyIDMwIG1pbnV0ZXMgaW4gdGhlIGFpciwgdGhlbiB0aGUgYXJyaXZhbCBkZWxheSBtdXN0IGJlIGF0IGxlYXN0IDMwIG1pbnV0ZXMgbGVzcyB0aGFuIHRoZSBkZXBhcnR1cmUgZGVsYXksIHdoaWNoIGlzIHN0YXRlZCBhcyBgZGVwX2RlbGF5IC0gYXJyX2RlbGF5ID4gMzBgLg0KDQpgYGB7ciBtYWtldXAzMH0NCmZpbHRlcihmbGlnaHRzLCBkZXBfZGVsYXkgPj0gNjAsIGRlcF9kZWxheSAtIGFycl9kZWxheSA+IDMwKQ0KYGBgDQoNCiMjIyMgKGcpIERlcGFydGVkIGJldHdlZW4gbWlkbmlnaHQgYW5kIDYgYW0gKGluY2x1c2l2ZSkNCg0KRmluZGluZyBmbGlnaHRzIHRoYXQgZGVwYXJ0ZWQgYmV0d2VlbiBtaWRuaWdodCBhbmQgNiBhLm0uIGlzIGNvbXBsaWNhdGVkIGJ5IHRoZSB3YXkgaW4gd2hpY2ggdGltZXMgYXJlIHJlcHJlc2VudGVkIGluIHRoZSBkYXRhLg0KSW4gYGRlcF90aW1lYCwgbWlkbmlnaHQgaXMgcmVwcmVzZW50ZWQgYnkgYDI0MDBgLCBub3QgYDBgLiBZb3UgY2FuIHZlcmlmeSB0aGlzIGJ5IGNoZWNraW5nIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIG9mIGRlcF90aW1lLg0KDQpgYGB7ciBjaGVja21pZG5pZ2h0fQ0Kc3VtbWFyeShmbGlnaHRzJGRlcF90aW1lKQ0KYGBgDQoNClRoaXMgaXMgYW4gZXhhbXBsZSBvZiB3aHkgaXQgaXMgYWx3YXlzIGdvb2QgdG8gY2hlY2sgdGhlIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB5b3VyIGRhdGEuIFVuZm9ydHVuYXRlbHksIHRoaXMgbWVhbnMgd2UgY2Fubm90IHNpbXBseSBjaGVjayB0aGF0IGBkZXBfdGltZSA8IDYwMGAsIGJlY2F1c2Ugd2UgYWxzbyBoYXZlIHRvIGNvbnNpZGVyIHRoZSBzcGVjaWFsIGNhc2Ugb2YgbWlkbmlnaHQuDQoNCmBgYHtyIGdldG1pZG5pZ2h0fQ0KZmlsdGVyKGZsaWdodHMsIGRlcF90aW1lIDw9IDYwMCB8IGRlcF90aW1lID09IDI0MDApDQpgYGANCg0KDQpBbHRlcm5hdGl2ZWx5LCB3ZSBjb3VsZCB1c2UgdGhlIFttb2R1bG8gb3BlcmF0b3JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL01vZHVsb19vcGVyYXRpb24pLCBgJSVgLiBUaGUgbW9kdWxvIG9wZXJhdG9yIHJldHVybnMgdGhlIHJlbWFpbmRlciBvZiBkaXZpc2lvbi4gTGV04oCZcyBzZWUgaG93IGhvdyB0aGlzIGFmZmVjdHMgb3VyIHRpbWVzLg0KDQpgYGB7ciBtb2R1bG99DQpjKDYwMCwgMTIwMCwgMjQwMCkgJSUgMjQwMA0KYGBgDQoNClNpbmNlIGAyNDAwICUlIDI0MDAgPT0gMGAgYW5kIGFsbCBvdGhlciB0aW1lcyBhcmUgbGVmdCB1bmNoYW5nZWQsIHdlIGNhbiBjb21wYXJlIHRoZSByZXN1bHQgb2YgdGhlIG1vZHVsbyBvcGVyYXRpb24gdG8gYDYwMGAsDQoNCmBgYHtyIG1vZDI0MDB9DQpmaWx0ZXIoZmxpZ2h0cywgZGVwX3RpbWUgJSUgMjQwMCA8PSA2MDApDQpgYGANCg0KVGhpcyBmaWx0ZXIgZXhwcmVzc2lvbiBpcyBtb3JlIGNvbXBhY3QsIGJ1dCBpdHMgcmVhZGFiaWxpdHkgd2lsbCBkZXBlbmRzIG9uIHRoZSBmYW1pbGlhcml0eSBvZiB0aGUgcmVhZGVyIHdpdGggbW9kdWxhciBhcml0aG1ldGljLg0KDQojIyMgMi4gQW5vdGhlciB1c2VmdWwgZHBseXIgZmlsdGVyaW5nIGhlbHBlciBpcyBgYmV0d2VlbigpYC4gV2hhdCBkb2VzIGl0IGRvPyBDYW4geW91IHVzZSBpdCB0byBzaW1wbGlmeSB0aGUgY29kZSBuZWVkZWQgdG8gYW5zd2VyIHRoZSBwcmV2aW91cyBjaGFsbGVuZ2VzPw0KDQpUaGUgZXhwcmVzc2lvbiBgYmV0d2Vlbih4LCBsZWZ0LCByaWdodClgIGlzIGVxdWl2YWxlbnQgdG8gYHggPj0gbGVmdCAmIHggPD0gcmlnaHRgLg0KDQpPZiB0aGUgYW5zd2VycyBpbiB0aGUgcHJldmlvdXMgcXVlc3Rpb24sIHdlIGNvdWxkIHNpbXBsaWZ5IHRoZSBzdGF0ZW1lbnQgb2YgKmRlcGFydGVkIGluIHN1bW1lciogKGBtb250aCA+PSA3ICYgbW9udGggPD0gOWApIHVzaW5nIHRoZSBgYmV0d2VlbigpYCBmdW5jdGlvbi4NCg0KYGBge3Igc3VtbWVyfQ0KZmlsdGVyKGZsaWdodHMsIGJldHdlZW4obW9udGgsIDcsIDkpKQ0KYGBgDQoNCiMjIyAzLiBIb3cgbWFueSBmbGlnaHRzIGhhdmUgYSBtaXNzaW5nIGBkZXBfdGltZWA/IFdoYXQgb3RoZXIgdmFyaWFibGVzIGFyZSBtaXNzaW5nPyBXaGF0IG1pZ2h0IHRoZXNlIHJvd3MgcmVwcmVzZW50Pw0KDQpGaW5kIHRoZSByb3dzIG9mIGZsaWdodHMgd2l0aCBhIG1pc3NpbmcgZGVwYXJ0dXJlIHRpbWUgKGBkZXBfdGltZWApIHVzaW5nIHRoZSBgaXMubmEoKWAgZnVuY3Rpb24uDQoNCmBgYHtyIG1pc3NpbmdfZGVwdGltZX0NCmZpbHRlcihmbGlnaHRzLCBpcy5uYShkZXBfdGltZSkpDQpgYGANCg0KTm90YWJseSwgdGhlIGFycml2YWwgdGltZSAoYGFycl90aW1lYCkgaXMgYWxzbyBtaXNzaW5nIGZvciB0aGVzZSByb3dzLiBUaGVzZSBzZWVtIHRvIGJlIGNhbmNlbGxlZCBmbGlnaHRzLg0KDQojIyMgNC4gV2h5IGlzIGBOQSBeIDBgIG5vdCBtaXNzaW5nPyBXaHkgaXMgYE5BIHwgVFJVRWAgbm90IG1pc3Npbmc/IFdoeSBpcyBgRkFMU0UgJiBOQWAgbm90IG1pc3Npbmc/IENhbiB5b3UgZmlndXJlIG91dCB0aGUgZ2VuZXJhbCBydWxlPyAoYE5BICogMGAgaXMgYSB0cmlja3kgY291bnRlcmV4YW1wbGUhKQ0KDQpgTkEgXiAwID09IDFgIHNpbmNlIGZvciBhbGwgbnVtZXJpYyB2YWx1ZXMgJHheMD0xJC4NCg0KYGBge3IgbmEwfQ0KTkFeMA0KYGBgDQoNCmBOQSB8IFRSVUVgIGlzIGBUUlVFYCBiZWNhdXNlIHRoZSB2YWx1ZSBvZiB0aGUgbWlzc2luZyBgVFJVRWAgb3IgYEZBTFNFYCwgIA0KJHgkIG9yIGBUUlVFYCBpcyBgVFJVRWAgZm9yIGFsbCB2YWx1ZXMgb2YgJHgkLg0KDQpgYGB7ciBuYXRydWV9DQpOQSB8IFRSVUUNCmBgYA0KDQoNCkxpa2V3aXNlLCBhbnl0aGluZyBhbmQgYEZBTFNFYCBpcyBhbHdheXMgYEZBTFNFYC4NCg0KYGBge3IgbmFmYWxzZX0NCk5BICYgRkFMU0UNCmBgYA0KDQpCZWNhdXNlIHRoZSB2YWx1ZSBvZiB0aGUgbWlzc2luZyBlbGVtZW50IG1hdHRlcnMgaW4gYE5BIHwgRkFMU0VgIGFuZCBgTkEgJiBUUlVFYCwgdGhlc2UgYXJlIG1pc3Npbmc6DQoNCmBgYHtyIG5hb3J9DQpOQSB8IEZBTFNFDQpOQSAmIFRSVUUNCmBgYA0KDQpTaW5jZSAkeCBcdGltZXMwPTAkIGZvciBhbGwgZmluaXRlLCBudW1lcmljICR4JCwgd2UgbWlnaHQgZXhwZWN0IGBOQSAqIDAgPT0gMGAsIGJ1dCB0aGF04oCZcyBub3QgdGhlIGNhc2UuDQoNCmBgYHtyIG5hdGltZXMwfQ0KTkEgKiAwDQpgYGANCg0KVGhlIHJlYXNvbiB0aGF0IGBOQSAqIDBgIGlzIG5vdCBlcXVhbCB0byBgMGAgaXMgdGhhdCAkeCBcdGltZXMgXGluZnR5JCBhbmQgJHggXHRpbWVzIC1caW5mdHkkIGlzIHVuZGVmaW5lZC4gUiByZXByZXNlbnRzIHVuZGVmaW5lZCByZXN1bHRzIGFzIGBOYU5gLCB3aGljaCBpcyBhbiBhYmJyZXZpYXRpb24gb2YgW25vdCBhIG51bWJlcl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTmFOKS4NCg0KYGBge3IgaW5mMH0NCkluZiAqIDANCi1JbmYgKiAwDQpgYGANCg0K