[Rd] transform.data.frame() ignores unnamed arguments when no named argument is provided
Sebastian Meyer
@eb@meyer @end|ng |rom |@u@de
Thu Mar 2 22:34:33 CET 2023
Note that ?transform.data.frame says arguments need to be named, so you
are testing unspecified behaviour. I guess this falls in a similar
category as the note
If some of the values are not vectors of the appropriate length,
you deserve whatever you get!
Experiments for a related Problem Report
(<https://bugs.r-project.org/show_bug.cgi?id=17890>) showed that
packages bravely ignore the caveats mentioned on the help page,
including to assume recycling the rows of the input data frame. I didn't
yet see any uses of unnamed arguments, though.
That said, I agree that transform.data.frame() should be improved. Maybe
unnamed arguments should always be ignored with a warning. My feeling is
that these would more often be usage errors than intentional, e.g.:
> data.frame(a = 1) |> transform(b = 2, a + 2) # "forgetting" a=
a b X3
1 1 2 3
I also think the implicit check.names=TRUE behaviour should be disabled. In
> list2DF(list(`A-1` = 1)) |> transform(B = 2)
A.1 B
1 1 2
transforming B should not touch the other columns.
I'm less sure about some other forms of undocumented behaviour as
described in Comment 6 of the linked PR.
Sebastian Meyer
Am 02.03.23 um 18:49 schrieb Antoine Fabri:
> Dear r-devel,
>
> See below:
>
>
> transform(data.frame(a = 1), 2, 3)
>
> #> a
>
> #> 1 1
>
>
> transform(data.frame(a = 1), b=2, 3)
>
> #> a b X3
>
> #> 1 1 2 3
>
>
> We need a small modification to make it work consistently, see below:
>
>
> transform.data.frame <- function (`_data`, ...) {
>
> e <- eval(substitute(list(...)), `_data`, parent.frame())
>
> tags <- names(e)
>
> ## NEW LINE -----------------------------------------------
>
> if (is.null(tags)) tags <- character(length(e))
>
> inx <- match(tags, names(`_data`))
>
> matched <- !is.na(inx)
>
> if (any(matched)) {
>
> `_data`[inx[matched]] <- e[matched]
>
> `_data` <- data.frame(`_data`)
>
> }
>
> if (!all(matched))
>
> do.call("data.frame", c(list(`_data`), e[!matched]))
>
> else `_data`
>
> }
>
>
> transform(data.frame(a = 1), 2, 3)
>
> #> a X2 X3
>
> #> 1 1 2 3
>
> transform(data.frame(a = 1), b=2, 3)
>
> #> a b X3
>
> #> 1 1 2 3
>
>
> Thanks,
>
>
> Antoine
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list