What this quiz covers
This quiz focuses on Filter, giving you a quick way to practice the rules, question types, and explanations that matter most for R Programming.
A tibble accounts has four rows. Account a: overdue = FALSE, flagged = FALSE. Account b: overdue = FALSE, flagged = TRUE. Account c: overdue = TRUE, flagged = FALSE. Account d: overdue = FALSE, flagged = NA.
Which accounts are returned by accounts %>% filter(!(overdue | flagged))?
a and db and ca onlya, b, and cR Programming Quiz
Practice Filter in R Programming with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.
This quiz focuses on Filter, giving you a quick way to practice the rules, question types, and explanations that matter most for R Programming.
Try each quiz question before looking at the correct answer. Use the explanations to review missed ideas, then come back to similar questions until the pattern feels familiar.
A tibble accounts has four rows. Account a: overdue = FALSE, flagged = FALSE. Account b: overdue = FALSE, flagged = TRUE. Account c: overdue = TRUE, flagged = FALSE. Account d: overdue = FALSE, flagged = NA.
Which accounts are returned by accounts %>% filter(!(overdue | flagged))?
a and db and ca only (correct answer)a, b, and cfilter() and logical operators in R, you need to trace the Boolean logic carefully for each row — and pay special attention to how R handles NA values, because they behave differently than you might expect.
The expression !(overdue | flagged) first evaluates overdue | flagged for each account, then negates the result. Only rows where this final expression evaluates to TRUE are kept. For account a (FALSE | FALSE = FALSE, negated → TRUE), it passes the filter. For account b (FALSE | TRUE = TRUE, negated → FALSE), it's excluded. For account c (TRUE | FALSE = TRUE, negated → FALSE), it's excluded. For account d (FALSE | NA = NA, negated → NA), R cannot determine the result — and filter() drops rows where the condition evaluates to NA, not TRUE. So only account a is returned, making C the correct answer.
Choice A is the most tempting trap. Account d seems "not overdue and not flagged" because its overdue is FALSE — but because flagged is NA, R can't confirm whether flagged is FALSE, so the whole OR expression becomes NA, and filter() silently drops it. Choice B returns the accounts that fail the filter (overdue or flagged), essentially the opposite logic. Choice D ignores the negation entirely and returns nearly everyone.
The key study tip: filter() keeps only TRUE, never NA or FALSE. Whenever you see NA in a filter condition, assume that row will be dropped unless you explicitly handle it with is.na().A tibble staff contains employee a in department A with salary = 40, employee b in department A with salary = 60, employee c in department B with salary = 80, and employee d in department B with salary = 100.
Which employees are returned by staff %>% group_by(department) %>% filter(salary > mean(salary))?
c and db and d (correct answer)b, c, and dd onlygroup_by() followed by filter() in a dplyr pipeline, the key insight is that any summary function like mean() inside filter() is computed per group, not across the entire dataset. This is what makes grouped filtering powerful — and tricky.
Here, group_by(department) splits the data into two groups before filter() runs. Department A contains employees a (salary 40) and b (salary 60), so the group mean is 240+60=50. Only b earns above 50, so b is kept. Department B contains employees c (salary 80) and d (salary 100), giving a group mean of 280+100=90. Only d earns above 90, so d is kept. The result is employees b and d — confirming B is correct.
A (c and d) is wrong because it applies the filter correctly only within Department B, while mistakenly dropping b from Department A. C (b, c, and d) would be the result if you compared each salary against the global mean of all four employees (440+60+80+100=70), ignoring the grouping entirely. D (only d) would result from comparing against the global maximum or some other single-threshold logic rather than per-group means.
A reliable study habit: whenever you see group_by() in a pipeline, mentally tag every subsequent operation as happening within each group independently. Functions like mean(), sum(), and n() all respect that grouping boundary.A tibble tasks contains these rows: task 1 has status = "open" and owner = "Sam"; task 2 has status = "pending" and owner = "Jo"; task 3 has status = "closed" and owner = "Jo"; task 4 has status = "open" and owner = NA.
Which task IDs are returned by tasks %>% filter(status %in% c("open", "pending") & !(owner %in% c("Sam", "Lee")))?
1 and 2 only2 only2 and 3 only2 and 4 only (correct answer)%in% with & (AND logic) and, critically, how NA values behave inside %in%.
The filter requires two things to be true: status %in% c("open", "pending") AND !(owner %in% c("Sam", "Lee")). Work through each task row by row. Task 1: status is "open" ✓, but owner is "Sam" — so !(owner %in% c("Sam", "Lee")) is FALSE. Task 1 is excluded. Task 2: status is "pending" ✓, owner is "Jo" which is not in the exclusion list ✓ — Task 2 passes. Task 3: status is "closed" — fails the first condition immediately. Task 3 is excluded. Task 4: status is "open" ✓, owner is NA — here's the key insight. NA %in% c("Sam", "Lee") returns FALSE (not NA), because %in% compares NA against each element and finds no match, returning FALSE. So !(FALSE) is TRUE, meaning Task 4 passes. The answer is D — Tasks 2 and 4.
Answer A is wrong because Task 1 is excluded (Sam is in the disallowed owner list). Answer B is wrong because it misses Task 4 — the trap is assuming NA values automatically disqualify a row. Answer C is wrong because Task 3 fails the status filter entirely ("closed" is not "open" or "pending").
Remember: %in% is NA-safe and always returns TRUE or FALSE — unlike ==, which propagates NA. When you see NA in a filter, ask yourself whether you're using == or %in%.A tibble results contains four rows in this order: row a has score = 80 and active = TRUE; row b has score = NA and active = TRUE; row c has score = 75 and active = FALSE; row d has score = 90 and active = NA.
Which rows are returned by results %>% filter(score >= 80, active)?
a is returned. (correct answer)a and d are returned.a and b are returned.a, b, and d are returned.filter() in R, every condition you pass must evaluate to TRUE for a row to be kept — and critically, NA is never treated as TRUE. This question tests whether you understand how filter() handles NA values in both numeric comparisons and logical columns.
Walk through each row against the two conditions score >= 80 and active:
80 >= 80 is TRUE, active is TRUE → both pass, row kept ✓NA >= 80 is NA, not TRUE → fails first condition, row dropped75 >= 80 is FALSE → fails immediately, row dropped90 >= 80 is TRUE, but active is NA, not TRUE → fails second condition, row droppeda survives both filters, making A the correct answer.
Answer B is wrong because row d has active = NA, and filter() drops any row where a condition evaluates to NA rather than TRUE. Answer C is wrong because row b has score = NA, so NA >= 80 produces NA, not TRUE — filter() discards it. Answer D combines both of these misconceptions, treating NA as if it passes a condition.
A reliable rule to remember: in filter(), a row is only kept when conditions return exactly TRUE — both FALSE and NA cause the row to be dropped. Whenever you see NA values in the data, immediately ask yourself how each condition will evaluate for that row.A tibble values has x values -1, 0, 10, 11, and NA, in that order.
What values remain after values %>% filter(x >= 0) %>% filter(x <= 10)?
-1, 0, and 100, 10, and NA0 only0 and 10 (correct answer)dplyr's filter(), the key things to remember are: conditions must be explicitly satisfied to pass through, and NA values are silently dropped — not kept, not flagged, just removed.
Here's the logic: starting with -1, 0, 10, 11, NA, the first filter x >= 0 removes -1 (fails the condition) and drops NA (because any comparison with NA returns NA, which filter() treats as FALSE). That leaves 0, 10, 11. The second filter x <= 10 then removes 11, leaving just 0 and 10 — making D the correct answer.
A is wrong because -1 fails the first filter (-1 >= 0 is FALSE), so it never makes it through the pipeline.
B is wrong because of the NA misconception — students often assume NA "slips through" since it's technically unknown. But filter() requires a condition to evaluate to TRUE; NA >= 0 returns NA, not TRUE, so NA is dropped.
C is wrong because 10 satisfies both conditions (10 >= 0 and 10 <= 10 are both TRUE), so there's no reason to exclude it. This answer likely results from misreading <= as <.
A reliable tip: whenever you see NA in a filter() question, assume it gets dropped unless the filter explicitly includes it using is.na(). This is one of the most common traps in R data-wrangling questions.A tibble readings has four rows. Row a: temp = NA, humidity = 70. Row b: temp = -2, humidity = NA. Row c: temp = 5, humidity = 60. Row d: temp = -1, humidity = 85.
Which rows are returned by readings %>% filter(is.na(temp) | temp < 0, humidity <= 80)?
a only (correct answer)a and ba, b, and da and ddplyr::filter() receives multiple comma-separated conditions, it treats the comma as a logical AND — but this interacts subtly with operator precedence when you mix | and , in the same call.
The expression filter(is.na(temp) | temp < 0, humidity <= 80) translates to: keep rows where (is.na(temp) | temp < 0) AND (humidity <= 80). Let's evaluate each row against both conditions:
is.na(temp) is TRUE, so the first condition passes. humidity = 70 ≤ 80 is TRUE. Both conditions met → kept.temp = -2 < 0 is TRUE, so the first condition passes. But humidity = NA ≤ 80 evaluates to NA, not TRUE. Filter drops rows that aren't clearly TRUE → excluded.temp = 5, so neither is.na(temp) nor temp < 0 is TRUE. First condition fails → excluded.temp = -1 < 0 is TRUE. But humidity = 85 ≤ 80 is FALSE. Second condition fails → excluded.a survives, confirming A is correct.
Choice B ignores that row b's NA humidity causes humidity <= 80 to return NA, not TRUE. Choice C additionally mishandles row d, where humidity clearly exceeds 80. Choice D correctly excludes row b for the right reason but wrongly includes row d despite humidity = 85 failing the cutoff.
The key study tip: always remember that filter() silently drops NA results — a condition returning NA behaves like FALSE, not TRUE.A tibble checks has four rows. Row 1: x = 6, group = "A", approved = FALSE. Row 2: x = 6, group = "B", approved = FALSE. Row 3: x = 2, group = "A", approved = TRUE. Row 4: x = 2, group = "B", approved = FALSE.
Which row IDs are returned by checks %>% filter(x > 5 & group == "A" | approved)?
1 only1 and 3 (correct answer)1, 2, and 32 and 3& and | in R's filter(), your first instinct should be to check operator precedence. In R (and most programming languages), & binds more tightly than |, so the expression x > 5 & group == "A" | approved is evaluated as (x > 5 & group == "A") | approved — not left-to-right as it might appear.
With that grouping clarified, evaluate each row: Row 1 has x = 6 > 5 ✓ and group == "A" ✓, so the left side is TRUE, making the whole expression TRUE. Row 2 has x = 6 > 5 ✓ but group == "B" ✗, so the left side is FALSE, and approved = FALSE means the right side is also FALSE — Row 2 is excluded. Row 3 has x = 2, so the left side is FALSE, but approved = TRUE saves it — Row 3 is included. Row 4 has a FALSE left side and approved = FALSE, so it's excluded. This gives you Rows 1 and 3, confirming B is correct.
Choice A is wrong because it ignores that approved = TRUE independently satisfies the | condition for Row 3. Choice C incorrectly includes Row 2 — a common mistake if you read the expression left-to-right without applying precedence, grouping it as (x > 5) & (group == "A" | approved) instead. Choice D drops Row 1 entirely, which clearly satisfies x > 5 & group == "A".
The study tip: whenever you mix & and |, mentally add parentheses around & expressions first. When in doubt, use explicit parentheses in your own code to avoid bugs.A tibble labels contains four rows in order: row 1 has code = "x"; row 2 has code = "X"; row 3 has code = "y"; row 4 has code = NA.
Which rows are returned by labels %>% filter(code != "x")?
2, 3, and 43 only2 and 3 only (correct answer)1, 2, and 3!= in R, the key concept to understand is how R handles NA values in logical comparisons. NA represents "not available" — an unknown value — and R treats any comparison involving NA as itself NA, not TRUE or FALSE. Since filter() only keeps rows where the condition evaluates to TRUE, rows where the condition returns NA are silently dropped.
Walking through each row: row 1 has code == "x", so "x" != "x" is FALSE — dropped. Row 2 has code == "X", and since R is case-sensitive by default, "X" != "x" is TRUE — kept. Row 3 has code == "y", so "y" != "x" is TRUE — kept. Row 4 has code == NA, so NA != "x" returns NA, not TRUE — dropped. This gives you rows 2 and 3 only, confirming C is correct.
Choice A is the most common trap: students assume NA simply means "not x," so they include row 4. But unknown ≠ "not x" in R's logic. Choice B incorrectly drops row 2, perhaps from forgetting that R's string comparison is case-sensitive, treating "X" and "x" as equal. Choice D would mean the filter kept row 1, which would require "x" != "x" to be TRUE — clearly wrong.
As a study tip, always remember: NA is contagious in comparisons. If you want to include or explicitly handle NA rows, use is.na() alongside your filter condition.A tibble orders has these rows: order 1 is in the East region with sales = 90 and priority = "high"; order 2 is in the West region with sales = 120 and priority = "high"; order 3 is in the East region with sales = 110 and priority = "low"; order 4 is in the East region with sales = 80 and priority = "low".
Which order IDs are returned by orders %>% filter(region == "East", sales > 100 | priority == "high")?
1, 2, and 32 and 3 only1 and 3 only (correct answer)3 only| (OR) operator binds more loosely than , (AND), but inside filter(), comma-separated conditions are evaluated as AND. So the expression region == "East", sales > 100 | priority == "high" means: region is East AND (sales > 100 OR priority is high). The parenthetical grouping happens automatically because | is evaluated before the comma acts as AND.
Now walk through each order. Order 1: East ✓, sales = 90 (not > 100), priority = "high" ✓ — the OR condition is satisfied, so this row passes. Order 2: West ✗ — immediately excluded since it fails the AND condition. Order 3: East ✓, sales = 110 ✓ — passes. Order 4: East ✓, sales = 80 and priority = "low" — both sides of the OR fail, so it's excluded. That leaves orders 1 and 3, making C correct.
Choice A incorrectly includes order 2, which is in the West region and therefore filtered out regardless of its other values. Choice B excludes order 1, likely from misreading the OR condition — because order 1's sales don't exceed 100, some students miss that its "high" priority still satisfies the OR clause. Choice D keeps only order 3, suggesting a misread of the entire condition as requiring all three criteria simultaneously.
Your study tip: whenever you see a filter() call mixing , and |, mentally add explicit parentheses around the | expression first — sales > 100 | priority == "high" — then apply AND with the remaining conditions. This prevents precedence mistakes on exam day.A tibble measurements contains row 1 with lower = 5, value = 5, and upper = 8; row 2 with lower = 2, value = 4, and upper = 4; and row 3 with lower = 1, value = 0, and upper = 3.
Which expression correctly filters rows whose value is within the row-specific bounds, including both endpoints?
filter(measurements, lower <= value, value <= upper) (correct answer)filter(measurements, lower < value, value < upper)filter(measurements, value <= lower, value >= upper)filter(measurements, lower <= value | value <= upper)<= and >= — not strict ones. A value exactly equal to a bound still qualifies. To require both conditions simultaneously, you chain them as separate arguments in filter(), which applies AND logic. Let's verify with the data: Row 1 has lower=5, value=5, upper=8 → 5 <= 5 ✓ and 5 <= 8 ✓; Row 2 has lower=2, value=4, upper=4 → 2 <= 4 ✓ and 4 <= 4 ✓; Row 3 has lower=1, value=0, upper=3 → 1 <= 0 ✗, so it's excluded. Answer A correctly returns rows 1 and 2.
Answer B uses strict inequalities (<), which excludes values that sit exactly on a boundary. Row 1 would fail because value == lower == 5, and Row 2 would fail because value == upper == 4 — so it returns no rows, which is wrong.
Answer C reverses the comparisons entirely (value <= lower and value >= upper), which tests whether the value is outside the bounds, not inside them.
Answer D uses | (OR logic) instead of AND. This keeps a row if it satisfies either condition alone — far too permissive and logically incorrect for a "within bounds" test.
Remember: multiple arguments inside filter() always combine with AND, and "including endpoints" always means <=/>=. These two facts together uniquely identify answer A.