Skip to content

Add .col pronoun to all condformat rules (closes #19) - #44

Merged
zeehio merged 1 commit into
mainfrom
claude/dot-col-pronoun
Jul 8, 2026
Merged

Add .col pronoun to all condformat rules (closes #19)#44
zeehio merged 1 commit into
mainfrom
claude/dot-col-pronoun

Conversation

@zeehio

@zeehio zeehio commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #19. Every CSS-based rule (rule_fill_discrete, rule_fill_gradient, rule_fill_gradient2, rule_fill_bar, rule_text_bold, rule_text_color, rule_css) evaluated its expression once and broadcast the result identically to every selected column, so a multi-column rule call couldn't express "each column's own condition" — only a shared one, or (with no expression) a warning-and-first-column-only fallback.

  • Added a shared eval_expression_per_column() helper (rule_helper.R) that evaluates the expression once per selected column, with a .col pronoun bound in the data mask to that column's own values. Wired it into all seven rules, replacing each rule's "evaluate once, mat[, columns] <- value" pattern with a per-column loop that also recomputes any auto-detected limits/midpoint/palette from that column alone — matching the semantics of chaining the rule once per column:

    # These two are now equivalent:
    condformat(iris) %>% rule_fill_discrete(c(Sepal.Length, Sepal.Width), .col > 3)
    
    condformat(iris) %>%
      rule_fill_discrete(Sepal.Length, Sepal.Length > 3) %>%
      rule_fill_discrete(Sepal.Width, Sepal.Width > 3)
  • expression now also defaults to .col when omitted, replacing the previous "applied to multiple columns, using column X ... please use an explicit expression" warning — each column now correctly uses its own values by default instead of silently only the first one.

  • While rewriting rule_text_bold's per-column assignment, replaced its row-selector matrix indexing (bold_or_not_mat[bold_or_not, columns] <- "bold") with an ifelse()-based approach that can't hit R's "NAs are not allowed in subscripted assignments" error if the expression evaluates to NA for some rows; also dropped an unused, vestigial intermediate matrix in the same function.

A related, separate finding (not fixed here)

While touching rule_css.R, I noticed its na.value constructor argument is accepted, documented, and stored on the rule object, but rule_to_cf_field.rule_css never actually reads rule[["na.value"]] — so it's a dead parameter (unlike every other rule, where na.value is applied). Left as-is since it's an unrelated, pre-existing gap and a behavior change of its own; happy to fix in a follow-up if wanted.

Test plan

  • Added a regression test per rule confirming the .col-based single-rule call produces output identical to chaining the rule once per column
  • Updated the two existing tests that asserted the now-removed multi-column warning
  • Updated roxygen docs, man pages (hand-synced since devtools::document() isn't available in this environment — worth a sanity check with devtools::document() before merge), and the introduction vignette
  • CI runs green

Generated by Claude Code

Every CSS-based rule (rule_fill_discrete, rule_fill_gradient,
rule_fill_gradient2, rule_fill_bar, rule_text_bold, rule_text_color,
rule_css) evaluated its expression once and broadcast the result
identically to every selected column, so a multi-column rule call
couldn't express "each column's own condition" - only a shared one,
or (with no expression) a warning-and-first-column-only fallback.

Add a shared eval_expression_per_column() helper (rule_helper.R) that
evaluates the expression once per selected column, with a `.col`
pronoun bound in the data mask to that column's own values. Wire it
into all seven rules, replacing their "evaluate once, mat[, columns] <-
value" pattern with a per-column loop that also recomputes any
auto-detected limits/midpoint/palette from that column alone, matching
the semantics of chaining the rule once per column.

rule_fill_discrete(c(Sepal.Length, Sepal.Width), .col > 3) is now
equivalent to chaining rule_fill_discrete(Sepal.Length, Sepal.Length > 3)
and rule_fill_discrete(Sepal.Width, Sepal.Width > 3).

expression now also defaults to `.col` when omitted, replacing the
previous "applied to multiple columns, using column X...please use an
explicit expression" warning - each column now correctly uses its own
values by default instead of silently only the first one.

While rewriting rule_text_bold's per-column assignment, replaced its
row-selector-based matrix indexing (bold_or_not_mat[bold_or_not,
columns] <- "bold") with an ifelse()-based approach that can't hit
R's "NAs are not allowed in subscripted assignments" error if the
expression evaluates to NA for some rows; also dropped an unused,
vestigial intermediate matrix in the same function.

Added regression tests for every rule confirming the .col-based
single-rule call produces identical output to chaining the rule once
per column, plus updated the two existing tests that asserted the
now-removed multi-column warning. Updated roxygen docs, man pages
(hand-synced since devtools::document() isn't available here), and
the introduction vignette.
@zeehio
zeehio merged commit 48b210a into main Jul 8, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.col pronoun

2 participants