Skip to Content
Course content

225: Mock Data Analysis Interview Walkthrough in R

Click on the "Edit" button in the top corner of the screen to edit your slide content.

In a data analysis interview, the technical challenge isn't just about whether you know the syntax—it's about how you handle it when things go wrong under pressure. I've sat on both sides of the table, and the biggest mistake I see isn't a lack of R knowledge; it's a failure to track how data transforms as it moves through a pipe.

Let's look at a snippet of code a candidate once wrote while trying to calculate the percentage of total revenue contributed by each product category. It looks perfectly logical at a glance, but it crashes immediately.

library(dplyr)

# Mock revenue data
df <- data.frame(
  category = c("Electronics", "Electronics", "Clothing", "Clothing", "Home"),
  revenue = c(100, 200, 50, 50, 300)
)

# The Goal: Category revenue and its % of total revenue
result <- df %>%
  group_by(category) %>%
  summarise(cat_total = sum(revenue)) %>%
  mutate(percent = cat_total / sum(revenue)) 

The "Missing Column" Panic

If you run this, R will throw an error: Error in sum(revenue) : object 'revenue' not found. When you're in a live coding interview, this is the moment where most people freeze. They look at the first line of the pipe, see that revenue exists in the dataframe, and start questioning if they misspelled something or if the library didn't load.

The problem is a fundamental misunderstanding of how summarise() works. In dplyr, summarise() doesn't just aggregate data; it collapses the dataframe. The moment that function finishes, the original revenue column is gone. All that remains are the grouping variable (category) and the new aggregated column (cat_total). When mutate() tries to call sum(revenue), it's looking for a column that no longer exists in the current pipeline state.

Recalculating the Total correctly

To fix this, you have two real options. The "quick fix" is to use the new column name, but that doesn't work here because sum(cat_total) would give you the grand total, while you're still grouped by category. Wait—actually, that would work because sum(cat_total) across the whole resulting dataframe is the same as the total revenue. But there's a cleaner way to handle this that shows the interviewer you understand data flow.

# Fix 1: Using the aggregated column
result <- df %>%
  group_by(category) %>%
  summarise(cat_total = sum(revenue)) %>%
  ungroup() %>% # Crucial: remove grouping before calculating grand total
  mutate(percent = cat_total / sum(cat_total))

# Fix 2: Calculating the total first (Better for complex pipelines)
grand_total <- sum(df$revenue)
result <- df %>%
  group_by(category) %>%
  summarise(cat_total = sum(revenue)) %>%
  mutate(percent = cat_total / grand_total)

I prefer the second approach in interviews. It separates the "global" calculation from the "grouped" calculation, making your intent crystal clear to the person watching your screen. Also, notice the ungroup() in the first fix. Forgetting to ungroup is a silent killer; it won't always throw an error, but it will make subsequent mutations behave in ways that will make you look like you don't know your data.

Thinking Aloud: The Interviewer's Perspective

When you hit a bug like this in an interview, don't go silent. I don't care if you make a mistake; I care how you debug it. I want to hear you say: "Wait, I'm getting a 'column not found' error. Let me check the state of the data after the summarise step."

A pro move is to break the pipe. If you're stuck, stop the pipe, assign the intermediate result to a variable, and print() it. It shows you have a systematic approach to debugging rather than just guessing and changing code randomly.

Structuring a Full Analysis Walkthrough

Now, let's apply this to a full mock prompt. Imagine the interviewer says: "Here is a dataset of user subscriptions. Tell me which plan has the highest churn rate and if there's a correlation between tenure and churn."

Your mental checklist should be:

  • Sanity Check: Check for NAs in the churn column. If you sum(churned) and there's one NA, the whole result is NA. Use na.rm = TRUE.
  • Feature Engineering: You'll likely need to create a 'tenure' column by subtracting the join date from the churn date.
  • Aggregation: Group by plan, calculate the mean of the binary 'churned' column (which is the churn rate).
  • Validation: Always double-check if your percentages add up to 100% or if your rates are between 0 and 1.

Keep your code modular. Instead of one giant 20-line pipe, break it into "Cleaning," "Analysis," and "Visualization" blocks. It makes your logic easier to follow and much easier to fix when that inevitable "object not found" error pops up.




📋 Practical Task

Analyzing User Retention for a SaaS Subscription Dataset

You are given a mock dataset of 1,000 users. Your task is to calculate the churn rate per subscription plan and identify the average tenure of users who stayed versus those who left.

# Setup the mock data
set.seed(42)
users <- data.frame(
  user_id = 1:1000,
  plan = sample(c("Basic", "Pro", "Enterprise"), 1000, replace = TRUE),
  churned = sample(c(0, 1), 1000, replace = TRUE, prob = c(0.7, 0.3)),
  tenure_months = sample(1:60, 1000, replace = TRUE)
)

# Introduce some NAs to simulate real-world data
users$tenure_months[sample(1:1000, 50)] <- NA

Requirements:

  1. Create a summary table showing the plan, the churn_rate (mean of the churned column), and the total_users per plan.
  2. Calculate the average tenure_months for churned users vs. non-churned users, ensuring you handle the NA values correctly.
  3. Combine these insights into a final data frame or list that could be presented to a stakeholder.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.