R Programming Language Certification Case Studies & Practical Application 3 — Questions and Answers
Question 1: A genomics researcher stores RNA-seq count data in a matrix with 20,000 genes (rows) and 48 samples (columns). She needs row-wise means efficiently. Which approach is fastest in R?
- apply(mat, 1, mean)
- rowMeans(mat) (Correct answer)
- sapply(1:nrow(mat), function(i) mean(mat[i,]))
- for(i in 1:nrow(mat)) means[i] <- mean(mat[i,])
Correct answer: rowMeans(mat)
rowMeans() is a vectorized C-level function specifically optimized for row means of matrices and is significantly faster than apply() or loops.
Question 2: An e-commerce company wants to segment customers into groups based on RFM (Recency, Frequency, Monetary) scores. After scaling the features, which R function performs k-means clustering?
- hclust(dist(rfm_scaled), method='ward.D2')
- kmeans(rfm_scaled, centers=5, nstart=25) (Correct answer)
- dbscan(rfm_scaled, eps=0.5)
- pam(rfm_scaled, k=5)
Correct answer: kmeans(rfm_scaled, centers=5, nstart=25)
kmeans() performs k-means clustering; centers specifies k and nstart>1 runs multiple random initializations to find a better solution.
Question 3: A data engineer reads a 2GB CSV file into R and immediately hits memory limits. Which strategy reduces memory usage most effectively before processing?
- Use read.csv() with colClasses specified to avoid character coercion
- Use data.table::fread() with select and colClasses to load only needed columns with correct types (Correct answer)
- Use readLines() to process line by line
- Convert the CSV to RDS format and re-read it
Correct answer: Use data.table::fread() with select and colClasses to load only needed columns with correct types
fread() with select loads only the needed columns and colClasses prevents over-allocation from default type inference, minimizing RAM usage from the start.
Question 4: A social scientist is running a multi-level model (mixed effects) to account for students nested within schools. Which R package and function is most appropriate?
- lm() from base R with school as a fixed effect
- lmer() from the lme4 package with (1|school) as a random intercept (Correct answer)
- glm() from base R with a school offset term
- nls() from base R specifying a nonlinear school effect
Correct answer: lmer() from the lme4 package with (1|school) as a random intercept
lme4's lmer() fits linear mixed-effects models; (1|school) specifies a random intercept for each school, correctly accounting for the nested structure.
Question 5: A sports analytics team scrapes game statistics from a website using rvest. After parsing, player names arrive as ' LeBron James ' with extra whitespace. Which function cleans this?
- gsub(' ', '', names)
- trimws(names)
- str_trim(names, side='both') from stringr
- Both B and C are correct (Correct answer)
Correct answer: Both B and C are correct
Both trimws() (base R) and stringr's str_trim() remove leading and trailing whitespace and produce identical results.
Question 6: An insurance actuary builds a gradient boosting model with xgboost and wants to interpret which features drive individual predictions. Which approach provides instance-level explanations?
- Use xgb.importance() to get global feature importance scores
- Use the SHAP package or xgboost's built-in SHAP values via predict(..., predcontrib=TRUE) (Correct answer)
- Examine the model's coefficients as in linear regression
- Run a partial dependence plot for every feature
Correct answer: Use the SHAP package or xgboost's built-in SHAP values via predict(..., predcontrib=TRUE)
SHAP (SHapley Additive exPlanations) values explain individual predictions by attributing contribution to each feature for that specific observation.
Question 7: A bioinformatician needs to apply a custom normalization function to each column of a data frame containing numeric assay data. Which is the most concise correct approach?
- for(col in names(df)) df[[col]] <- normalize(df[[col]])
- df[] <- lapply(df, normalize) (Correct answer)
- apply(df, 2, normalize)
- sapply(df, normalize, simplify=FALSE)
Correct answer: df[] <- lapply(df, normalize)
df[] <- lapply(df, normalize) applies the function to each column and preserves the data frame structure, making it the most idiomatic and concise approach.
A genomics researcher stores RNA-seq count data in a matrix with 20,000 genes (rows) and 48 samples (columns).
She needs row-wise means efficiently.
Which approach is fastest in R?