Skip to content

fix: robust argument evaluation for NSE functions in loops#62

Open
laresbernardo wants to merge 2 commits into
mainfrom
fix-corr-var-loop
Open

fix: robust argument evaluation for NSE functions in loops#62
laresbernardo wants to merge 2 commits into
mainfrom
fix-corr-var-loop

Conversation

@laresbernardo

@laresbernardo laresbernardo commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Description

This PR fixes a critical bug introduced in version 5.2.8 that caused corr_var(), ci_var(), and balance_data() to crash when used in for loops, lapply(), or Shiny reactive environments where column references are parameterized (e.g., names(iris)[i], n_iris[i], etc.).

What was happening:

  1. Data-Mask Collision: Previously, eval(substitute(var), df) was evaluated in the context of the data frame columns df. If the expression passed to var contained the dataset name (e.g., names(iris)[i] or iris[i]), R looked for a column named "iris" within iris first, resulting in evaluation failures.
  2. Vector Evaluation Bug: If a character column vector itself (e.g., df[[5]]) was evaluated, is.character(var) would evaluate to TRUE. The function then mistakenly treated the entire character vector of length $N$ as the column name, causing downstream logic (like if (!var %in% colnames(rs$cor))) to crash with the condition has length > 1.
  3. Broken ci_var() unquoting: In ci_var(), the unquoted string "Fare" inside summarise(mean(!!var, ...)) evaluated to the string literal "Fare" instead of the column symbol Fare, which returned NA values with warnings.

Proposed Changes:

  1. Evaluate substitute(var) in parent.frame(): Evaluating in the parent environment prevents R from searching inside the data frame's columns for symbols like iris or df.
  2. Strict Length & Type Checking: Added checks (is.character(var_eval) && length(var_eval) == 1 && !inherits(var_eval, "try-error")) to guarantee we only use the evaluated representation if it successfully resolves to a single string column name.
  3. Correct Symbols in ci_var(): ci_var() now assigns sym(var_eval) (a symbol) or enquo(var) (a quosure), allowing it to properly unquote and evaluate inside tidyverse verbs.

Files Changed

  • R/confidence.R: Robust parsing logic in ci_var(), returning a symbol/quosure for correct tidyverse unquoting.
  • R/correlations.R: Robust parsing logic in corr_var().
  • R/wrangling.R: Robust parsing logic in balance_data().

Verification Plan

Automated/Manual verification

Tested locally using devtools::load_all() with the following scenarios:

# 1. Loop test (AlexanderKlug's scenario)
n_iris <- names(iris)
for (i in 1:5) {
  print(corr_var(iris, var = n_iris[i], plot = FALSE))
}

# 2. ci_var bare name & string tests
ci_var(dft, Fare, Pclass)
ci_var(dft, "Fare")

# 3. balance_data bare name & string tests
balance_data(dft, Survived, rate = 1)
balance_data(dft, "Survived", rate = 0.5)

All of the above executed without errors and computed correct statistics/correlations.

Reported here: https://stackoverflow.com/questions/78437460/problem-with-assigning-variables-in-a-for-loop-with-lares-corr-var-function/78443283?noredirect=1#comment141107140_78443283

@laresbernardo laresbernardo self-assigned this Jul 9, 2026
@laresbernardo laresbernardo added the bug Something isn't working label Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant