Rename column when a symbol is named in xnew_data() - #102
Conversation
A named symbol was translated into `xnew_seq()`, which returns a one column tibble named after the symbol, so `tidyr::expand()` stored it as a data frame column (`Length$lengths`). The tibble is now renamed and the argument name dropped so that a new column of that name is generated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Fixes xnew_data() behavior when a bare-symbol argument is also named (e.g., Length = lengths), which previously caused tidyr::expand() to create a nested data-frame column (printed as Length$lengths) instead of a proper new column.
Changes:
- Propagate argument names into translation so that named bare symbols are converted to a one-column tibble renamed to the supplied name, while dropping the outer argument name to avoid nested columns in
tidyr::expand(). - Add regression tests covering column naming and
.length_outbehavior for named symbols (including factors). - Add an example documenting that naming a variable creates a new column of that name.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
R/xnew-data.R |
Renames one-column tibbles produced from bare symbols when the argument is named, and drops the outer name to avoid nested columns in tidyr::expand(). |
tests/testthat/test-xnew-data.R |
Adds regression tests for named-symbol column creation and .length_out behavior (including factor level preservation). |
man/xnew_data.Rd |
Updates generated documentation examples to illustrate the named-symbol behavior. |
Files not reviewed (1)
- man/xnew_data.Rd: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
StefanoMezzini
left a comment
There was a problem hiding this comment.
added some tests for using a preexisting vector object instead of a data.frame column
StefanoMezzini
left a comment
There was a problem hiding this comment.
accidentally approved instead of requesting changes. see requested changes above
Co-authored-by: Stefano Mezzini <stefano@poissonconsulting.ca>
Co-authored-by: joethorley <613671+joethorley@users.noreply.github.com>
There was a problem hiding this comment.
Claude Code Review
Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.
Tip: disable this comment in your organization's Code Review settings.
The comment was dropped from R/xnew-data.R but not from man/xnew_data.Rd, leaving the roxygen source and the generated Rd out of sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Stefano Mezzini <stefano@poissonconsulting.ca>
|
The code seems to be working well, but I can't comment on whether the changes are ideal. I understand what the diffused expressions are doing, but I am not familiar enough with the functions to provide any additional useful feedback, so I'll leave that to @krlmlr. |
krlmlr
left a comment
There was a problem hiding this comment.
Why not just
expr_translate_xnew_data <- function(expr, name, length_out) {
if (!is_symbol(expr)) {
return(expr)
}
if (name == "") {
# Unnamed: return tibble
expr(xnew_seq(!!expr, .length_out = !!length_out))
} else {
# Named: return first column of tibble as a vector,
# new name will be applied externally
expr(xnew_seq(!!expr, .length_out = !!length_out)[[1]])
}
}and with just the imap() change? What am I missing?
Co-authored-by: Kirill Müller <krlmlr@users.noreply.github.com>
Co-authored-by: Kirill Müller <krlmlr@users.noreply.github.com>
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
On the other hand, names_enquos <- function(...) {
names(rlang::enquos(...))
}
names_enquos(a = 3)
#> [1] "a"
names_enquos(a, 3)
#> [1] "" ""Created on 2026-09-02 with reprex v2.1.1 |
The one column tibble is load-bearing. d <- tibble::tibble(a = 1:5 + 0.5, b = factor(letters[1:5]))
tidyr::expand(d, z = factor(c("b", "a"), levels = letters[1:5]))$z
#> [1] a b c d e
#> Levels: a b c d e
tidyr::expand(d, tibble::tibble(z = factor(c("b", "a"), levels = letters[1:5])))$z
#> [1] a b
#> Levels: a b c d eThat level expansion silently discards On Your question did turn up something real though. xnew_data(d, z = new_seq(b, .length_out = 2))$z
#> [1] a b c d eThat is the idiom shown in |
|
@krlmlr see response drafted by Fable above. |
|
I was thinking that we could just always wrap in tibbles and pass them as unnamed objects to |
|
This was the problem reprex library(newdata)
Year <- data.frame(lengths = 1:2)
xnew_data(Year, Length = lengths)
#> # A tibble: 2 × 2
#> lengths Length$lengths
#> <int> <int>
#> 1 1 1
#> 2 1 2Created on 2026-09-08 with reprex v2.1.1 |
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
A named argument evaluating to NULL produced a zero column tibble that tidyr::expand() crossed as zero rows; it is now dropped as on main. The user's quosure is nested inside one evaluated in the package namespace instead of inlining the function object, so backtraces show xnew_column() and the quosure stays small. The name handling reduces to unname() and the details section now states how named arguments of each shape are treated. Regenerates the stale Rd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-authored-by: Kirill Müller <krlmlr@users.noreply.github.com>
Co-authored-by: Kirill Müller <krlmlr@users.noreply.github.com>
Co-authored-by: Kirill Müller <krlmlr@users.noreply.github.com>
This reverts commit 596ee3e.
This reverts commit a7bf18a.
Passing a data frame where a vector is expected, such as xnew_data(data, Length = data.frame(lengths = 10:12)), failed with the S3 dispatch error "no applicable method for 'new_seq'". A default method now names the supported classes and what was received. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Closes #99. Closes #109.
xnew_data(Year, Length = lengths)produced a data frame columnLength$lengthsinstead of a new columnLength, and other named arguments either ignored.length_outor were packed the same way.A bare symbol is translated into
xnew_seq(), which returns a one column tibble named after the symbol.When the argument was also named,
tidyr::expand()stored that tibble as a data frame column.A named bare vector reached
expand()directly, which expands a factor to all of its levels and so discarded.length_outand.obs_only.Every named argument is now passed through
xnew_column(), which applies the argument name to the value itself and drops the outer name:tidyr::nesting(), is packed into a data frame column as before;NULLis dropped, asexpand()did before.The user's quosure is nested inside one evaluated in the package namespace so the internal helper is in scope without inlining the function object.
The semantics of named arguments are documented in the details section.
Adds regression tests and examples.
R CMD check: 0 errors, 0 warnings, 0 notes.Name handling inside
xobs_only()is tracked separately in #111.🤖 Generated with Claude Code