What this quiz covers
This quiz focuses on Vector Indexing, giving you a quick way to practice the rules, question types, and explanations that matter most for R Programming.
Consider the following code:
x <- c(alpha = 10, alphabet = 20, beta = 30)
y <- x[names(x) != "alphabet"]
What is returned by unname(y[c("beta", "alp", "alpha")])?
c(30, 10, NA)c(30, 20, 10)c(10, NA, 30)c(30, NA, 10)R Programming Quiz
Practice Vector Indexing 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 Vector Indexing, 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.
Consider the following code:
x <- c(alpha = 10, alphabet = 20, beta = 30)
y <- x[names(x) != "alphabet"]
What is returned by unname(y[c("beta", "alp", "alpha")])?
c(30, 10, NA)c(30, 20, 10)c(10, NA, 30)c(30, NA, 10) (correct answer)names(), trace each step carefully before jumping to conclusions.
Start with the initial vector: x <- c(alpha = 10, alphabet = 20, beta = 30). The condition names(x) != "alphabet" evaluates to TRUE, FALSE, TRUE, so y becomes c(alpha = 10, beta = 30) — the "alphabet" element is dropped entirely.
Now you subset y using y[c("beta", "alp", "alpha")]. R looks up each name in y: "beta" exists and returns 30, "alp" does not exist and returns NA, and "alpha" exists and returns 10. So y[c("beta", "alp", "alpha")] gives c(beta = 30, alp = NA, alpha = 10). Wrapping this in unname() strips the names, leaving c(30, NA, 10) — that's D.
Choice A, c(30, 10, NA), swaps the positions of 10 and NA, which would only happen if you looked up "alpha" before "alp" — but the order of the index vector determines the output order. Choice B, c(30, 20, 10), incorrectly assumes "alp" partially matches "alphabet" and retrieves 20; partial matching does not apply to [ (single-bracket) subsetting by name. Choice C, c(10, NA, 30), reflects looking up the names in the wrong order, perhaps confusing the original x indexing with y.
A key tip: remember that [ requires exact name matches — partial matching only occurs with $ and [[. Jot this distinction down, as it's a frequent trap in R subsetting questions.Consider the following code:
x <- c("1" = 10, "3" = 20, "2" = 30)
idx <- c(1, "2")
What is returned by unname(x[idx])?
c(10, 30) (correct answer)c(10, 20)c(NA, 30)c(20, 30)x <- c("1" = 10, "3" = 20, "2" = 30) creates a named vector where the names are "1", "3", "2" and the values are 10, 20, 30 respectively. Then idx <- c(1, "2") combines a number and a string. Because R vectors must be homogeneous, the 1 gets coerced to the character "1", making idx effectively c("1", "2"). Now x[idx] performs name-based lookup: it finds the element named "1" (value 10) and the element named "2" (value 30). After unname() strips the names, the result is c(10, 30), confirming A is correct.
B (c(10, 20)) reflects the trap of assuming "2" retrieves the second position (value 20). It doesn't — once the index is character, R matches by name, and the name "2" maps to value 30.
C (c(NA, 30)) would occur if the integer 1 stayed as a positional index (finding 10) alongside a name-based "2", but that's not how coercion works — the whole index becomes character, so "1" matches the name successfully.
D (c(20, 30)) would result from positional lookup of positions 2 and 3, which ignores both the coercion and name-matching entirely.
The key study tip: whenever you mix types inside c(), check what R coerces to — character beats numeric, and character indices always trigger name-based subsetting.Consider the following R code:
x <- setNames(c(8, 3, 5, 9, 2), letters[1:5])
What is returned by unname(x[c(3, 0, 1, 3, 6)])?
c(5, 8, 5, NA) (correct answer)c(5, NA, 8, 5, NA)c(5, 8, 5)c(5, 8, NA, 5)NA. Keeping both rules in mind is the key to this problem.
Start by building x: it's a named numeric vector c(a=8, b=3, c=5, d=9, e=2) with five elements (positions 1-5). Now evaluate x[c(3, 0, 1, 3, 6)] step by step. The index 0 is silently ignored — it contributes nothing to the result, so it's as if you wrote x[c(3, 1, 3, 6)]. Position 3 gives 5, position 1 gives 8, position 3 again gives 5, and position 6 is out of bounds, returning NA. So before unname(), you have c(c=5, a=8, c=5, NA) — four elements. Wrapping it in unname() simply strips the names, leaving c(5, 8, 5, NA). That confirms A is correct.
B is wrong because it includes five elements — it treats the 0 index as if it produces an NA slot, which it does not. C drops the NA entirely, ignoring the out-of-bounds index 6 rather than returning NA for it. D misorders the elements, placing NA in the third position as if index 6 were evaluated before index 3.
A handy rule to memorize: in R, 0 is the "ghost index" — it vanishes silently, while any index beyond the vector's length becomes NA. Whenever you see a mix of zero and out-of-range indices in a subsetting question, apply these two rules separately before combining the result.v <- c(a=1,b=2,c=3); v[c('c','a')] is equivalent to?
y <- c(p=1,q=2); unname(y[c('r','q')]) returns?
x <- c(5,6,7,8); x[c(1,3,1)] + 1 returns?
x <- c(10,20,30,40); x[c(TRUE,FALSE)][2] returns?
x <- 1:6; x[(x > 3) & (x %% 2 == 0)] returns?
Consider the following R code:
x <- c(p = 4, q = 6, r = 8)
What is returned by unname(x[c(TRUE, FALSE, TRUE, TRUE, FALSE)])?
c(4, 8)c(4, 8, NA) (correct answer)c(4, 8, 4)c(4, NA, 8)x has 3 elements, but the logical index c(TRUE, FALSE, TRUE, TRUE, FALSE) has 5. R recycles x to match the longer index vector, effectively treating x as if it were c(4, 6, 8, NA, NA) — padding with NA once the original values are exhausted. Applying the logical mask c(TRUE, FALSE, TRUE, TRUE, FALSE) selects positions 1, 3, and 4, giving you c(4, 8, NA). The unname() call then strips the element names (p, r), leaving an unnamed numeric vector c(4, 8, NA). That makes B the correct answer.
A (c(4, 8)) is tempting because it matches the TRUE positions in x's original length, ignoring that the index is longer than x. C (c(4, 8, 4)) reflects a misunderstanding of recycling — students sometimes think R recycles x circularly (wrapping back to 4), but recycling applies to x padding with NA, not looping. D (c(4, NA, 8)) would result from a different mask pattern and doesn't match any reasonable interpretation of this indexing operation.
As a study tip: whenever you see a logical index vector that is longer than the object it's subsetting, immediately ask yourself what R does with out-of-bounds positions — the answer is always NA, not recycled values from the original vector.Let x <- c(10, 20, 30, 40, 50). What is returned by the following expression?
x[c(5.8, 2.2, 2.9)][c(3, 1)]
c(30, NA)c(50, 20)c(20, 50) (correct answer)c(20, 10)x <- c(10, 20, 30, 40, 50). The first operation is x[c(5.8, 2.2, 2.9)]. A crucial R behavior: decimal indices are silently truncated toward zero, not rounded. So 5.8 becomes 5, 2.2 becomes 2, and 2.9 becomes 2. This gives you x[c(5, 2, 2)], which returns c(50, 20, 20) — a three-element vector.
Now apply the second index: c(50, 20, 20)[c(3, 1)]. You're selecting position 3 first, then position 1, from this intermediate vector. Position 3 is 20, and position 1 is 50. The result is c(20, 50) — answer C.
A (c(30, NA)) is wrong on two levels: it misapplies the truncation (treating 2.9 as 3 via rounding) and incorrectly assumes a position goes out of bounds. B (c(50, 20)) gets the intermediate vector right but reverses the final indexing order — it applies c(1, 3) rather than c(3, 1). D (c(20, 10)) likely confuses truncation with some other logic, substituting position 1 (10) where position 1 of the intermediate result is actually 50.
The key study tip: remember that R truncates decimal indices (floor toward zero), it does not round them. Pair that with careful left-to-right evaluation of chained brackets and you'll avoid all the traps here.Consider a vector with duplicated names:
x <- c(red = 2, blue = 4, red = 6)
What is returned by unname(x[c("red", "green", "red")])?
c(2, NA, 6)c(2, NA, 2) (correct answer)c(2, 6, 2)c(6, NA, 6)[ operator always returns the first match it finds. So when you write x["red"] on a vector where "red" appears twice (at positions 1 and 3), R returns only the first element, which has value 2 — not 6. This is the critical trap here. For missing names like "green", R returns NA with the name "green", since no match exists. Finally, unname() strips all names from the result, leaving you with plain values. Putting it together: x[c("red", "green", "red")] returns c(red=2, green=NA, red=2), and after unname() you get c(2, NA, 2) — confirming B is correct.
Choice A, c(2, NA, 6), reflects the misconception that the second "red" lookup retrieves a different match — the third element with value 6. But R always stops at the first matching name, so you'd never get 6 this way. Choice C, c(2, 6, 2), assumes no NA is produced and that R somehow finds 6 for the middle lookup of "green" — neither is true. Choice D, c(6, NA, 6), wrongly supposes R returns the last match for "red", giving 6 both times.
As a study tip: whenever you see duplicate names in a vector, remember that name-based subsetting in R is first-match-only — this is a frequent exam trap when combined with NA behavior for unrecognized names.Let x <- 11:17. What is returned by unname(x[c(TRUE, NA, FALSE)])?
c(11, 14, 17, NA, NA)c(11, NA, 14, 17, NA)c(11, 14, 17)c(11, NA, 14, NA, 17) (correct answer)NA in an index returns NA in the output.
Here, x <- 11:17 gives a vector of length 7, and the index c(TRUE, NA, FALSE) has length 3. R recycles it to length 7: TRUE, NA, FALSE, TRUE, NA, FALSE, TRUE. Now apply this element-wise — position 1 (TRUE) returns 11, position 2 (NA) returns NA, position 3 (FALSE) drops 13, position 4 (TRUE) returns 14, position 5 (NA) returns NA, position 6 (FALSE) drops 16, position 7 (TRUE) returns 17. The result is c(11, NA, 14, NA, 17), confirming D is correct.
A (c(11, 14, 17, NA, NA)) incorrectly groups the TRUE selections first and appends NAs at the end — R doesn't reorder results this way. B (c(11, NA, 14, 17, NA)) suggests the recycled pattern was only partially applied, missing the second NA before 17. C (c(11, 14, 17)) ignores NA indexing entirely, as if NA behaved like FALSE — a common misconception. Unlike FALSE, which silently drops elements, NA explicitly preserves a "missing" slot in the output.
As a study tip, remember the mantra: FALSE drops, NA keeps a hole. Whenever you see logical indexing with recycling and NA, sketch out the recycled pattern explicitly — it prevents nearly every mistake on questions like this.Consider the following code:
x <- c(a = 5, b = 8, c = 13)
u <- unname(x[NA])
v <- unname(x[c(NA, 2)])
Which pair correctly describes u and v?
u is c(NA, NA, NA); v is c(NA, 8). (correct answer)u is c(NA); v is c(NA, 8).u is c(NA, NA, NA); v is c(NA, 8, NA).u is c(NA); v is c(5, 8).NA, the result depends on how many NA values you provide — R treats each NA as a request for one unknown element and returns one NA per index position.
Start with x <- c(a = 5, b = 8, c = 13). When you write x[NA], R interprets NA as a single logical or integer index. Because x has three elements and NA is a single logical value, R recycles it across all three positions — each position is unknown, so you get c(NA, NA, NA). After unname() strips the names, u is indeed c(NA, NA, NA).
For v, the index is c(NA, 2) — two explicit positions. Position 1 is NA (unknown element), and position 2 requests the second element of x, which is 8. So v becomes c(NA, 8) after unname(). This confirms answer A is correct.
Answer B is wrong because it misunderstands the logical recycling: x[NA] with a single NA applied to a length-3 vector produces three NAs, not one. Answer D shares this mistake and additionally claims x[c(NA, 2)] returns c(5, 8), confusing NA indexing with some kind of sequential fill. Answer C gets u right but incorrectly adds a third element to v — c(NA, 2) has only two index positions, so the result can only have two elements.
A good rule of thumb: the length of your index vector determines the length of the output. A single NA used as a logical mask on a length-3 vector recycles to three NAs, while c(NA, 2) always yields exactly two elements.Consider the following R code:
x <- c(a = 4, b = 7, c = 9, d = 12, e = 15)
What is the value of x[-c(2, 5)][c(TRUE, FALSE)]?
c(a = 4, c = 9)c(a = 4, c = 9, d = 12)c(a = 4, d = 12) (correct answer)c(c = 9, d = 12)x <- c(a = 4, b = 7, c = 9, d = 12, e = 15). The first operation, x[-c(2, 5)], uses negative integer indexing to drop elements at positions 2 and 5 — that's b = 7 and e = 15. You're left with c(a = 4, c = 9, d = 12), a three-element named vector.
Now apply [c(TRUE, FALSE)] to that result. Logical indexing recycles the pattern when the vector is longer than the logical index. Your three-element vector gets matched against TRUE, FALSE, TRUE (the pattern TRUE, FALSE repeats to length 3). Positions 1 and 3 are TRUE, position 2 is FALSE, so you keep a = 4 and d = 12. That confirms C is correct.
Choice A, c(a = 4, c = 9), would result if you applied c(TRUE, FALSE) without recycling — as if the pattern only ran once and stopped, dropping the third element entirely. Choice B, c(a = 4, c = 9, d = 12), ignores the logical subsetting altogether and just returns the intermediate result. Choice D, c(c = 9, d = 12), suggests keeping positions 2 and 3, which would only happen if the logical vector were c(FALSE, TRUE, TRUE) — a misapplication of the recycling pattern.
The study tip here: always remember that logical recycling wraps around. Write out the recycled vector explicitly when you're unsure — it prevents nearly every mistake in this type of question.Let x <- c(2, 4, 6, 8). What happens when R evaluates x[c(-2, NA)]?
c(2, 6, 8).c(2, NA, 6, 8).c(NA, 2, 6, 8).NA values in the same subscript vector — doing so triggers an immediate error.
With x <- c(2, 4, 6, 8), the expression x[c(-2, NA)] asks R to simultaneously exclude element 2 (via -2) while also including an NA position. R cannot reconcile these two operations and throws the error: "only 0's may be mixed with negative subscripts." So B is correct.
A is tempting because -2 alone would correctly drop the second element, returning c(2, 6, 8). But that logic only holds when the subscript vector contains exclusively negative integers — the NA breaks that contract entirely.
C and D reflect a misunderstanding of how NA works in positive subscripting. When you use positive indices, NA acts as a placeholder and returns NA in the corresponding output position — that's the behavior behind C and D. However, this rule applies to positive subscript contexts, not negative ones. Mixing the two modes isn't just unusual — it's illegal in R.
A useful mental model: think of negative and positive subscripts as two incompatible "modes." R forces you to pick one. An NA in a subscript vector is treated as a member of the positive mode, so pairing it with a negative index creates a conflict. When you see any mix of negative integers and NA in a subscript, expect an error.