[R] Using the pipe, |>, syntax with "names<-"

Bert Gunter
Sun, 21 Jul 2024 15:01:23 -0000

Wow!
Yes, this is very clever -- way too clever for me -- and meets my
criteria for a solution.

I think it's also another piece of evidence of why piping in base R is
not suited for complex/nested assignments, as discussed in Deepayan's
response.

Maybe someone could offer a better Tidydata piping solution just for
completeness?

Best,
Bert

On Sun, Jul 21, 2024 at 7:48?AM Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
>
> This
> - is non-destructive (does not change z)
> - passes the renamed z onto further pipe legs
> - does not use \(x)...
>
> It works by boxing z, operating on the boxed version and then unboxing it.
>
>   z <- data.frame(a = 1:3, b = letters[1:3])
>   z |> list(x = _) |> within(names(x)[2] <- "foo") |>
_$x
>   ##   a foo
>   ## 1 1   a
>   ## 2 2   b
>   ## 3 3   c
>
> On Sat, Jul 20, 2024 at 4:07?PM Bert Gunter <bgunter.4567 at
gmail.com> wrote:
> >
> > This post is likely pretty useless;  it is motivated by a recent post
> > from "Val" that was elegantly answered using Tidyverse
constructs, but
> > I wondered how to do it using base R only. Along the way, I ran into
> > the following question to which I think my answer (below) is pretty
> > awful. I would be interested in more elegant base R approaches. So...
> >
> > z <- data.frame(a = 1:3, b = letters[1:3])
> > > z
> >   a h
> > 1 1 a
> > 2 2 b
> > 3 3 c
> >
> > Suppose I want to change the name of the second column of z from
'b'
> > to 'foo' . This is very easy using nested function syntax by:
> >
> > names(z)[2] <- "foo"
> > > z
> >   a foo
> > 1 1   a
> > 2 2   b
> > 3 3   c
> >
> > Now suppose I wanted to do this using |> syntax, along the lines
of:
> >
> > z |> names()[2] <- "foo"  ## throws an error
> >
> > Slightly fancier is:
> >
> > z |> (\(x)names(x)[2] <- "b")()
> > ## does nothing, but does not throw an error.
> >
> > However, the following, which resulted from a more careful read of
> > ?names works (after changing the name of the second column back to
"b"
> > of course):
> >
> > z |>(\(x) "names<-"(x,value =
"[<-"(names(x),2,'foo')))()
> > >z
> >   a foo
> > 1 1   a
> > 2 2   b
> > 3 3   c
> >
> > This qualifies to me as "pretty awful." I'm sure there
are better ways
> > to do this using pipe syntax, so I would appreciate any better
> > approaches.
> >
> > Best,
> > Bert
> >
> > ______________________________________________
> > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
>
>
>
> --
> Statistics & Software Consulting
> GKX Group, GKX Associates Inc.
> tel: 1-877-GKX-GROUP
> email: ggrothendieck at gmail.com