R Programming Quiz: Style Conventions
10 questions · exam conditions
0:00
Style ConventionsQuestion 1 of 10

At the top level of a script, a model-fitting function is called with two named arguments. The result must be stored in an object named result.

Which statement uses the preferred assignment convention both outside and inside the function call?

result = fit_model(data <- training, max_iter <- 100)
result = fit_model(data = training, max_iter = 100)
result <- fit_model(data = training, max_iter = 100)
result <- fit_model(data <- training, max_iter <- 100)
← Back to quizzes

R Programming Quiz

R Programming Quiz: Style Conventions

Practice Style Conventions in R Programming with focused quiz questions that help you check what you know, review explanations, and build confidence with test-style prompts.

What this quiz covers

This quiz focuses on Style Conventions, giving you a quick way to practice the rules, question types, and explanations that matter most for R Programming.

How to use this quiz

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.

All questions

Question 1

At the top level of a script, a model-fitting function is called with two named arguments. The result must be stored in an object named result.

Which statement uses the preferred assignment convention both outside and inside the function call?

  1. result = fit_model(data <- training, max_iter <- 100)
  2. result = fit_model(data = training, max_iter = 100)
  3. result <- fit_model(data = training, max_iter = 100) (correct answer)
  4. result <- fit_model(data <- training, max_iter <- 100)
Explanation: In R, two different operators perform assignment, and knowing where to use each one is a core style convention. The <- operator is the idiomatic choice for variable assignment at the top level of a script. The = operator, by contrast, is the conventional choice for argument passing inside function calls. Mixing these up is one of the most common style mistakes beginners make. Option C — result <- fit_model(data = training, max_iter = 100) — follows both conventions correctly: <- assigns the output to result, while = passes named arguments inside the function. This is exactly what the Google R Style Guide and the tidyverse style guide both recommend. Option A uses = for the top-level assignment (result = ...), which technically works but violates R's preferred convention for variable assignment. It also misuses <- inside the function call, which is the second error described below. Option B correctly uses = inside the function call, but still uses = for the top-level assignment — half right, but the outer assignment is non-idiomatic. Option D uses <- correctly on the outside, but using <- inside a function call is a serious mistake: data <- training inside a call doesn't pass an argument — it creates a variable in the calling environment as a side effect and can cause subtle, hard-to-debug bugs. A quick memory rule: arrow for objects, equals for arguments. Whenever you're assigning a result to a named variable in your script, reach for <-; whenever you're naming a parameter inside (), use =.

Question 2

A script excludes records created before a system migration. Those records contain timestamps recorded in a different time zone, so comparing them directly with current records would be misleading.

Which comment best follows conventions for comment spacing, sentence case, and explaining intent rather than merely restating code?

  1. # Filter rows where the timestamp is before the migration cutoff date.
  2. #exclude pre-migration records because timestamps use a different time zone.
  3. # The next line compares every timestamp with the configured migration cutoff.
  4. # Exclude pre-migration records; their timestamps use a different time zone. (correct answer)
Explanation: When evaluating R comment style, you need to check three things simultaneously: formatting conventions (spacing after #, sentence case), and whether the comment explains why the code does something rather than just what it does. That last distinction is the heart of this question. Option D — # Exclude pre-migration records; their timestamps use a different time zone. — nails all three criteria. It has a space after #, starts with a capital letter, uses an imperative verb ("Exclude") rather than passive description, and critically, the semicolon connects the action to its reason. You understand not just what's being filtered, but why those records can't be trusted. Option A fails on intent. It describes the mechanical action ("Filter rows where the timestamp is before the migration cutoff date") without explaining the time zone problem that motivates it. A future reader still wouldn't know why pre-migration records are excluded. Option B has two formatting problems: no space after #, and it starts with a lowercase letter (exclude). Even if the content were perfect, these violations make it immediately wrong in a style-focused question. Option C commits the classic anti-pattern of narrating the next line of code ("The next line compares every timestamp..."). Good comments explain intent, not execution. Describing what the code does mechanically adds no value a reader can't get by reading the code itself. As a study strategy, remember the mantra: format, case, intent. When a comment question appears, scan each option in that order — eliminate formatting errors first, then ask whether the surviving options explain why, not just what.

Question 3

A top-level assignment must create the exact character value She said "ready".. The team normally uses double-quoted strings but follows the tidyverse exception that avoids unnecessary escaping when a string itself contains double quotation marks.

Which assignment best follows both the required value and the stated style convention?

  1. status <- "She said \"ready\"."
  2. status = 'She said "ready".'
  3. status <- 'She said "ready".' (correct answer)
  4. status <- "She said 'ready'."
Explanation: When working with string literals in R, you face two simultaneous constraints: producing the exact character value required, and following team style conventions. Here, those conventions come from the tidyverse style guide, which prefers <- for assignment and recommends using single quotes to delimit strings that contain double quotes — specifically to avoid unnecessary backslash escaping. Option C, status <- 'She said "ready".', satisfies everything. The single-quoted delimiter lets the double quotes inside the string appear literally, with no escaping needed. The <- operator honors the tidyverse preference for top-level assignment. The resulting value is exactly She said "ready".. Now consider why the others fall short. Option A uses <- correctly but wraps the string in double quotes, forcing you to escape the internal double quotes with backslashes (\"). That escape-heavy approach is precisely what the tidyverse style guide says to avoid when a cleaner alternative exists. Option B produces the correct string value — single-quoted strings containing double quotes work fine in R — but uses = for assignment instead of <-. The tidyverse style guide explicitly reserves = for function arguments, not top-level assignments, so B violates the style convention. Option D uses <- and double quotes without any escaping, but it changes the actual string content: the output would be She said 'ready'. with single quotes, not double quotes — a completely different value from what was required. A useful pattern to remember: when a string contains double quotes, switch to single-quote delimiters rather than escaping. That's the tidyverse "avoid unnecessary escaping" rule in practice.

Question 4

A team is refactoring internal R objects. A variable stores a customer identifier, and a function computes an order total. All internal call sites can be updated.

Which pair of replacement names best follows tidyverse naming conventions while also communicating each object's role?

  1. Variable: customer_id; function: calculate_total() (correct answer)
  2. Variable: customerId; function: calculateTotal()
  3. Variable: customer.id; function: calculate.total()
  4. Variable: calculate_customer; function: total_value()
Explanation: When writing R code that follows the tidyverse style guide, naming conventions are about two things simultaneously: readability and consistency. The tidyverse (and the broader R community) has settled on snake_case — lowercase words separated by underscores — for both variables and functions. Names should also reflect what something is (for variables) or what something does (for functions). Option A gets both right. customer_id uses snake_case and clearly describes the variable as an identifier belonging to a customer. calculate_total() uses snake_case and starts with a verb, which is the tidyverse convention for functions — it tells you the function does something (calculates). This is your correct answer. Option B uses camelCase, which is common in JavaScript or Java but explicitly discouraged in the tidyverse style guide. While technically readable, it's inconsistent with R community norms, making B wrong. Option C uses dot.case, which mixes up R's naming history — dots were used in older base R code and can create ambiguity since dots have special meaning in R's S3 method dispatch system (e.g., print.data.frame). This makes C a subtle but real stylistic and technical trap. Option D is wrong on meaning, not style. calculate_customer doesn't describe a variable storing an ID — it sounds like a function. And total_value lacks a verb, making it feel like a variable rather than a function. The names are semantically backwards. A quick study tip: for any tidyverse naming question, ask yourself three things — Is it snake_case? Does the variable describe a thing? Does the function start with a verb?

Question 5

The following lines are intended to compute the median of df$value while removing missing values. Assume all four lines would otherwise refer to valid objects.

Which line follows tidyverse spacing conventions most closely?

  1. result <- stats::median(df$value, na.rm = TRUE) (correct answer)
  2. result<-stats::median(df$value, na.rm = TRUE)
  3. result <- stats :: median(df$value, na.rm = TRUE)
  4. result <- stats::median(df $ value, na.rm=TRUE)
Explanation: When writing R code in the tidyverse style, spacing around operators and namespacing syntax follows specific conventions defined in the tidyverse style guide. Questions like this test whether you know those rules well enough to spot violations even when the code is otherwise valid. The tidyverse style guide requires spaces around the assignment operator <- and around = inside function arguments, but explicitly prohibits spaces around :: (the namespace operator) and around $. Option A follows all of these rules perfectly: spaces flank <-, na.rm = TRUE has proper spacing around =, and stats::median and df$value have no extra spaces around :: or $. Option B violates the most fundamental rule by omitting spaces around <-, writing result<-stats::median(...). This is one of the most recognizable style violations in R. Option C introduces illegal spaces around ::, writing stats :: median(...) — the style guide treats :: like a tight-binding operator that should never be padded with whitespace. Option D commits two errors simultaneously: it adds a space around $ in df $ value and drops the space around = in na.rm=TRUE, which should always be na.rm = TRUE. A useful study tip: think of tightly-binding operators like ::, $, and @ as "glue" — no spaces allowed around them. Meanwhile, loose operators like <- and = inside arguments always get spaces on both sides. Memorizing this two-tier rule will help you quickly eliminate style violations on exam questions.

Question 6

The function normalize() must immediately return numeric() for an empty input so that summary functions are not evaluated. For nonempty input, it should return the normalized expression. The team prefers explicit return() only for early exits.

Which implementation best satisfies both the behavior and the stated style convention?

  1. normalize <- function(x) { if (length(x) == 0) { return(numeric()) } return((x - min(x)) / (max(x) - min(x))) }
  2. normalize <- function(x) { if (length(x) == 0) { return(numeric()) } (x - min(x)) / (max(x) - min(x)) } (correct answer)
  3. normalize <- function(x) { if(length(x)==0) return(numeric()) (x-min(x))/(max(x)-min(x)) }
  4. normalize <- function(x) { if (length(x) == 0) { numeric() } (x - min(x)) / (max(x) - min(x)) }
Explanation: When working with R functions, you need to balance two concerns simultaneously: correct behavior and team style conventions. Here, the style rule is specific — use explicit return() only for early exits, letting R's implicit return handle the normal result. The right implementation is B. The early-exit guard return(numeric()) fires immediately when the input is empty, preventing min() and max() from being called on an empty vector (which would produce warnings and Inf/-Inf values). For the non-empty case, the normalization expression sits as the last line with no return() wrapper — R automatically returns the value of the final evaluated expression, which satisfies the "no explicit return for normal results" convention perfectly. A is wrong despite being functionally correct. It uses return(...) on the final normalization expression, which violates the stated style convention. The team explicitly reserves explicit return() for early exits only. C is functionally equivalent to B and actually follows the style rule, but it violates standard R formatting conventions — missing spaces around operators and after if, and using a single-line if without braces. This would typically fail a code review on style grounds, making it a weaker answer than B. D is the most dangerous distractor. Removing return() from the early exit means R won't stop at the if block — it will evaluate the empty-vector condition, produce numeric(), and then continue to evaluate the normalization expression anyway, triggering the exact errors the guard was meant to prevent. As a study tip: when a question mentions a style convention, treat it as a hard constraint, not a preference — eliminate any answer that breaks it even if the behavior seems correct.

Question 7

An if statement must print one message when is_valid is true and a different message otherwise. The team wants a conventional multi-line layout.

Which version best follows tidyverse brace and else placement conventions?

  1. if (is_valid) { message("Accepted") } else { message("Rejected") }
  2. if (is_valid) { message("Accepted") } else { message("Rejected") }
  3. if (is_valid) { message("Accepted") } else { message("Rejected") }
  4. if (is_valid) { message("Accepted") } else { message("Rejected") } (correct answer)
Explanation: When writing conditional logic in R, the tidyverse style guide gives specific rules about brace and else placement that you should internalize as a team convention — not just personal preference. The core rules are: the opening brace { lives at the end of the line that opens the block, body lines are indented two spaces, the closing brace } sits on its own line, and crucially, else appears on the same line as the closing } of the preceding if block. Option D follows all of these rules exactly. The { opens on the if line, the body is indented, and } else { appears together on one line — keeping the flow readable while signaling that the conditional isn't finished yet. Option A places the opening { on its own line (sometimes called "Allman" style), which violates tidyverse convention even though it's valid R. Option B compounds multiple errors: the body isn't indented, and else appears on a separate line after }, which actually causes a parsing risk in R — if the } closes the if block completely before R sees else, you can get unexpected behavior. Option C puts everything on a single line, which might work for trivial cases but fails the question's explicit requirement for a "conventional multi-line layout" and sacrifices readability for complex logic. A useful memory rule: in tidyverse R style, } and else are inseparable neighbors — they always appear on the same line together. If you see them on separate lines, that's a red flag.

Question 8

A ggplot2 expression contains a plot constructor followed by two layers. The expression is being reformatted without changing its behavior.

Which version follows the conventional tidyverse layout for adding plot layers?

  1. ggplot(sales, aes(date, revenue)) + geom_line() + labs(title = "Revenue") (correct answer)
  2. `ggplot(sales, aes(date, revenue))
    • geom_line()
    • labs(title = "Revenue")`
  3. ggplot(sales, aes(date, revenue)) | geom_line() | labs(title = "Revenue")
  4. ggplot(sales, aes(date, revenue))+ geom_line()+ labs(title = "Revenue")
Explanation: When writing multi-layer ggplot2 code, the key convention to understand is where the + operator is placed relative to line breaks. In tidyverse style, the + that connects layers always goes at the end of the line, not the beginning — this mirrors how the pipe operator |> is typically written in tidyverse pipelines, and it tells R that the expression continues on the next line. Option A is the correct answer because it places + at the end of each line before breaking, keeping the constructor and its layers clearly connected while following the tidyverse style guide. The indentation of subsequent layers also makes the code visually clean and readable. Option B places the + at the start of each new line. While this actually works syntactically in R (because R looks back at the previous line when a line begins with an operator), it violates the tidyverse style convention and can confuse readers expecting the standard layout. It's a functional but non-conventional choice. Option C uses the pipe operator | between layers, which is simply wrong. The |> or %>% pipe is used to pass data between functions, but ggplot2 layers are combined with +, not pipes. This reflects a common conceptual mix-up between pipelines and plot layering. Option D is close, but omits the space before +. Tidyverse style guidelines call for spaces around operators for readability — + rather than + immediately adjacent to the preceding expression. A quick rule of thumb: in ggplot2, always put + at the end of the line, with a space before it, and indent each new layer consistently.

Question 9

A data transformation uses the base R pipe and is long enough to span several lines. The operations must remain in the order shown.

Which formatting best follows tidyverse pipe style?

  1. customers |> filter(active) |> arrange(joined_at) |> select(customer_id, joined_at)
  2. customers |> filter(active) |> arrange(joined_at) |> select(customer_id, joined_at)
  3. customers |> filter(active) |> arrange(joined_at) |> select(customer_id, joined_at) (correct answer)
  4. customers|> filter(active)|> arrange(joined_at)|> select(customer_id, joined_at)
Explanation: When writing multi-step pipe chains in R, the tidyverse style guide gives clear rules about spacing and line breaks that make code readable and scannable. The key principles are: each piped step gets its own line, the pipe operator |> sits at the end of the current line (not the start of the next), and each continuation line is indented by two spaces. Option C follows all of these rules exactly. The object customers sits alone on the first line, |> closes each subsequent line, and filter(), arrange(), and select() are each indented two spaces — making the sequence of transformations visually clear and easy to follow. Option A places the |> at the beginning of each new line rather than the end of the previous one. While this is a valid style in some communities, it contradicts the tidyverse convention, which puts the pipe at the line's end so you immediately see "this line continues." Option B breaks lines mid-chain but doesn't consistently apply indentation, and the line breaks appear after the |> operator mid-expression rather than after a complete step — making the structure harder to parse visually. Option D is almost correct but omits the spaces before |> on each line (writing customers|> instead of customers |>). The tidyverse style requires a space on both sides of the pipe operator for readability. A helpful memory anchor: think of the pipe as a period at the end of a sentence — it belongs at the end of the line, followed by the next step indented below. Spotting missing spaces around |> or misplaced line breaks will quickly eliminate wrong answers on formatting questions.

Question 10

A call to summarise_customer_activity() is too long to remain readable on one line. Each named argument is a distinct logical component of the call.

Which layout best follows tidyverse conventions for a long function call?

  1. summary <- summarise_customer_activity( customer_data, start_date = first_date, end_date = last_date, include_returns = TRUE)
  2. summary <- summarise_customer_activity( customer_data, start_date = first_date, end_date = last_date, include_returns = TRUE ) (correct answer)
  3. summary <- summarise_customer_activity (customer_data, start_date = first_date, end_date = last_date, include_returns = TRUE)
  4. summary <- summarise_customer_activity(customer_data, start_date = first_date, end_date = last_date, include_returns = TRUE )
Explanation: When formatting long function calls in R, the tidyverse style guide has a clear principle: if a call is too long for one line, each argument should get its own line, indented by two spaces, with the closing parenthesis on its own line beneath them. This creates visual symmetry and makes each argument equally scannable. Option B follows this exactly — the opening parenthesis stays attached to the function name, each argument sits on its own indented line, and the closing parenthesis closes cleanly beneath. This structure makes it immediately obvious how many arguments exist and lets you add, remove, or reorder them without disrupting the surrounding code. Option A keeps the opening break but then crowds multiple arguments onto the same lines. This defeats the purpose of breaking the call apart — start_date and end_date are logically distinct components that deserve their own lines. Option C makes a critical structural error: it separates the function name from its opening parenthesis, placing ( on the next line. R actually permits this syntactically, but it's explicitly discouraged because it visually severs the function from its call, making the code harder to parse at a glance. Option D partially applies the convention by breaking after the first argument but then bunches the remaining arguments together — inconsistent formatting that mixes the compact and expanded styles without committing to either. A useful pattern to remember: in tidyverse style, think of a long function call like a bulleted list — one item per line, consistent indentation, and a clean closing marker. If you see arguments sharing a line, that's your signal something is off.