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])> za 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"> za 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')))()>za 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
Nope, I still got it wrong: None of my approaches work. :( So my query remains: how to do it via piping with |> ? Bert On Sat, Jul 20, 2024 at 1:06?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
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