Skip to content

Conversation

@SchmidtPaul
Copy link
Contributor

Summary

Implements named vector support for col.regions and col.text parameters in both desplot() and ggdesplot().

Closes #10

This enhancement allows users to specify colors that match factor levels by name rather than positional order, similar to ggplot2::scale_color_manual().

Problem

As described in #10, colors previously had to be provided in the same order as factor levels:

# Factor levels: A, B, C
# Colors MUST be in this exact order
col.regions <- c("red", "blue", "green")  # A=red, B=blue, C=green

If you wanted to specify colors in a different order, you had to manually reorder them to match the factor levels.

Solution
Named vectors now allow order-independent color specification:

Features
✅ Order-independent matching: Colors match factor levels by name, not position
✅ Graceful fallback: Missing names trigger a warning and fall back to positional matching with R's standard vector recycling
✅ Backward compatible: Unnamed vectors work exactly as before
✅ Works for both: desplot() (lattice) and ggdesplot() (ggplot2)
✅ Two parameters: Supports both col.regions (fill colors) and col.text (outline colors)

Implementation Details
Modified files:

R/desplot.R: Lines 413-429 (col.regions), Lines 565-580 (col.text)
R/ggdesplot.R: Lines 262-278 (col.regions), Lines 407-422 (col.text)
test_named_colors.R: Comprehensive test suite
Edge cases handled:

✅ Extra names (ignored)
✅ Partial names (warns and falls back)
✅ NULL names (original behavior)

Reprex

# Test Script for Named Vector Color Support - Issue #10
# devtools::install()
library(desplot)

# Simple test data: 2 rows x 3 columns, 3 factor levels
test_data <- data.frame(
  row = rep(1:2, each = 3),
  col = rep(1:3, times = 2),
  treat = factor(rep(c("A", "B", "C"), length.out = 6))
)

# TEST 1: Named vector - forward order
my_colors <- c("skyblue", "pink", "lightgreen")
names(my_colors) <- c("A", "B", "C")
desplot(
  test_data,
  treat ~ col * row,
  col.regions = my_colors,
  main = "Test 1: Named forward",
  gg = FALSE
)

desplot(
  test_data,
  treat ~ col * row,
  col.regions = my_colors,
  main = "Test 1: Named forward (gg)",
  gg = TRUE
)

# TEST 2: Named vector - reversed order (KEY TEST from issue #10)
my_colors_rev <- c("skyblue", "pink", "lightgreen")
names(my_colors_rev) <- c("C", "B", "A") # REVERSED!
desplot(
  test_data,
  treat ~ col * row,
  col.regions = my_colors_rev,
  main = "Test 2: Named reversed",
  gg = FALSE
)

desplot(
  test_data,
  treat ~ col * row,
  col.regions = my_colors_rev,
  main = "Test 2: Named reversed (gg)",
  gg = TRUE
)

# TEST 3: Partial names (should warn and fallback)
partial_colors <- c("red", "blue")
names(partial_colors) <- c("A", "B") # Missing C
desplot(
  test_data,
  treat ~ col * row,
  col.regions = partial_colors,
  main = "Test 3: Partial names",
  gg = FALSE
)
#> Warning in desplot(test_data, treat ~ col * row, col.regions = partial_colors,
#> : col.regions: Not all factor levels found in provided names. Missing: C.
#> Falling back to positional matching.

desplot(
  test_data,
  treat ~ col * row,
  col.regions = partial_colors,
  main = "Test 3: Partial names (gg)",
  gg = TRUE
)
#> Warning in ggdesplot(form = form, data = data, num.string = num.string, :
#> col.regions: Not all factor levels found in provided names. Missing: C. Falling
#> back to positional matching.

# TEST 4: Extra names (should work, extras ignored)
extra_colors <- c("purple", "orange", "brown", "yellow")
names(extra_colors) <- c("A", "B", "C", "D") # D doesn't exist
desplot(
  test_data,
  treat ~ col * row,
  col.regions = extra_colors,
  main = "Test 4: Extra names",
  gg = FALSE
)

desplot(
  test_data,
  treat ~ col * row,
  col.regions = extra_colors,
  main = "Test 4: Extra names (gg)",
  gg = TRUE
)

# TEST 5: Unnamed vector (backward compatibility)
unnamed_colors <- c("coral", "cyan", "gold")
desplot(
  test_data,
  treat ~ col * row,
  col.regions = unnamed_colors,
  main = "Test 5: Unnamed",
  gg = FALSE
)

desplot(
  test_data,
  treat ~ col * row,
  col.regions = unnamed_colors,
  main = "Test 5: Unnamed (gg)",
  gg = TRUE
)

# TEST 6: Named col.text
text_colors <- c("red", "blue", "green")
names(text_colors) <- c("C", "B", "A") # Reversed
desplot(
  test_data,
  treat ~ col * row,
  col = treat,
  col.text = text_colors,
  cex = 5,
  main = "Test 6: Named col.text",
  gg = FALSE
)

desplot(
  test_data,
  treat ~ col * row,
  col = treat,
  col.text = text_colors,
  cex = 5,
  main = "Test 6: Named col.text (gg)",
  gg = TRUE
)

Created on 2025-11-14 with reprex v2.1.1

Implements issue kwstat#10 - Support for named vectors in color parameters,
similar to ggplot2's scale_color_manual(). This allows users to specify
colors that match factor levels by name rather than positional order.

Changes:
- desplot.R: Add named vector handling for col.regions (line 413) and
  col.text (line 565)
- ggdesplot.R: Add named vector handling for col.regions (line 262) and
  col.text (line 407)
- test_named_colors.R: Comprehensive test suite covering 7 scenarios:
  * Forward order named vectors
  * Reversed order named vectors (key test case from issue kwstat#10)
  * Partial names (warns and falls back to positional)
  * Extra names (works, extras ignored)
  * Unnamed vectors (backward compatibility)
  * Named col.text
  * Both col.regions and col.text with named vectors

Features:
- Named vectors match colors to factor levels by name
- Order-independent: c("red"="A", "blue"="B") same as c("blue"="B", "red"="A")
- Graceful fallback: Missing names trigger warning + positional matching
- Backward compatible: Unnamed vectors work exactly as before
- Works for both desplot (lattice) and ggdesplot (ggplot2)

Addresses: kwstat#10
@kwstat kwstat merged commit f6c3f4d into kwstat:main Dec 5, 2025
1 check passed
@kwstat
Copy link
Owner

kwstat commented Dec 5, 2025

Thanks

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.

Named vector for col.regions and col.text

3 participants