Mateo Obregón
2023-Dec-29 14:13 UTC
[Rd] eval(parse()) within mutate() returning same value for all rows
Hi all- Looking through stackoverflow for R string combining examples, I found the following from 3 years ago: <https://stackoverflow.com/questions/63881854/how-to-format-strings-using-values-from-other-column-in-r> The top answer suggests to use eval(parse(sprintf())). I tried the suggestion and it did not return the expected combines strings. I thought that this might be an issue with some leftover values being reused, so I explicitly eval() with a new.env():> library(dplyr) > df <- tibble(words=c("%s plus %s equals %s"),args=c("1,1,2","2,2,4","3,3,6"))> df |> mutate(combined = eval(parse(text=sprintf("sprintf('%s', %s)", words,args)), envir=new.env())) # A tibble: 3 ? 3 words args combined <chr> <chr> <chr> 1 %s plus %s equals %s 1,1,2 3 plus 3 equals 6 2 %s plus %s equals %s 2,2,4 3 plus 3 equals 6 3 %s plus %s equals %s 3,3,6 3 plus 3 equals 6 The `combined` is not what I was expecting, as the same last eval() is returned for all three rows. Am I missing something? What has changed in the past three years? Mateo. -- Mateo Obreg?n
Dirk Eddelbuettel
2023-Dec-29 15:35 UTC
[Rd] eval(parse()) within mutate() returning same value for all rows
On 29 December 2023 at 14:13, Mateo Obreg?n wrote: | Hi all- | | Looking through stackoverflow for R string combining examples, I found the | following from 3 years ago: | | <https://stackoverflow.com/questions/63881854/how-to-format-strings-using-values-from-other-column-in-r> | | The top answer suggests to use eval(parse(sprintf())). I tried the suggestion Well: > fortunes::fortune(106) If the answer is parse() you should usually rethink the question. -- Thomas Lumley R-help (February 2005) > | and it did not return the expected combines strings. I thought that this might | be an issue with some leftover values being reused, so I explicitly eval() | with a new.env(): | | > library(dplyr) | > df <- tibble(words=c("%s plus %s equals %s"), | args=c("1,1,2","2,2,4","3,3,6")) | > df |> mutate(combined = eval(parse(text=sprintf("sprintf('%s', %s)", words, | args)), envir=new.env())) | | # A tibble: 3 ? 3 | words args combined | <chr> <chr> <chr> | 1 %s plus %s equals %s 1,1,2 3 plus 3 equals 6 | 2 %s plus %s equals %s 2,2,4 3 plus 3 equals 6 | 3 %s plus %s equals %s 3,3,6 3 plus 3 equals 6 | | The `combined` is not what I was expecting, as the same last eval() is | returned for all three rows. | | Am I missing something? What has changed in the past three years? Nothing if you use the first answer which relies only on base R and still works: > words <- c('%s + %s equal %s', '%s + %s equal %s') > arguments <- c('1,1,2', '2,2,4') > df <- data.frame(words, arguments) > df words arguments 1 %s + %s equal %s 1,1,2 2 %s + %s equal %s 2,2,4 > df$combined <- apply(df, 1, function(x) do.call(sprintf, c(as.list(strsplit(x[2], ',')[[1]]), fmt = x[[1]]))) > df words arguments combined 1 %s + %s equal %s 1,1,2 1 + 1 equal 2 2 %s + %s equal %s 2,2,4 2 + 2 equal 4 > I am not the best person to answer what may have changed in `dplyr` in those three years -- and neither is this list which is primarily concerned with developing R itself. Dirk -- dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
Jan Gorecki
2023-Dec-29 16:10 UTC
[Rd] eval(parse()) within mutate() returning same value for all rows
Unless you are able to reproduce the problem without dplyr then you should submit your question to dplyr issues tracker. R-devel is for issues in R, not in a third party packages. On Fri, Dec 29, 2023, 15:13 Mateo Obreg?n <obregonmateo at gmail.com> wrote:> Hi all- > > Looking through stackoverflow for R string combining examples, I found the > following from 3 years ago: > > < > https://stackoverflow.com/questions/63881854/how-to-format-strings-using-values-from-other-column-in-r > > > > The top answer suggests to use eval(parse(sprintf())). I tried the > suggestion > and it did not return the expected combines strings. I thought that this > might > be an issue with some leftover values being reused, so I explicitly eval() > with a new.env(): > > > library(dplyr) > > df <- tibble(words=c("%s plus %s equals %s"), > args=c("1,1,2","2,2,4","3,3,6")) > > df |> mutate(combined = eval(parse(text=sprintf("sprintf('%s', %s)", > words, > args)), envir=new.env())) > > # A tibble: 3 ? 3 > words args combined > <chr> <chr> <chr> > 1 %s plus %s equals %s 1,1,2 3 plus 3 equals 6 > 2 %s plus %s equals %s 2,2,4 3 plus 3 equals 6 > 3 %s plus %s equals %s 3,3,6 3 plus 3 equals 6 > > The `combined` is not what I was expecting, as the same last eval() is > returned for all three rows. > > Am I missing something? What has changed in the past three years? > > Mateo. > -- > Mateo Obreg?n > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >[[alternative HTML version deleted]]
Duncan Murdoch
2023-Dec-29 17:22 UTC
[Rd] eval(parse()) within mutate() returning same value for all rows
On 29/12/2023 9:13 a.m., Mateo Obreg?n wrote:> Hi all- > > Looking through stackoverflow for R string combining examples, I found the > following from 3 years ago: > > <https://stackoverflow.com/questions/63881854/how-to-format-strings-using-values-from-other-column-in-r> > > The top answer suggests to use eval(parse(sprintf())). I tried the suggestion > and it did not return the expected combines strings. I thought that this might > be an issue with some leftover values being reused, so I explicitly eval() > with a new.env(): > >> library(dplyr) >> df <- tibble(words=c("%s plus %s equals %s"), > args=c("1,1,2","2,2,4","3,3,6")) >> df |> mutate(combined = eval(parse(text=sprintf("sprintf('%s', %s)", words, > args)), envir=new.env())) > > # A tibble: 3 ? 3 > words args combined > <chr> <chr> <chr> > 1 %s plus %s equals %s 1,1,2 3 plus 3 equals 6 > 2 %s plus %s equals %s 2,2,4 3 plus 3 equals 6 > 3 %s plus %s equals %s 3,3,6 3 plus 3 equals 6 > > The `combined` is not what I was expecting, as the same last eval() is > returned for all three rows. > > Am I missing something? What has changed in the past three years? >I don't know if this is a change, but when `eval()` is passed an expression vector, it evaluates the elements in order and returns the value of the last one. This is only partially documented: "Value: The result of evaluating the object: for an expression vector this is the result of evaluating the last element." That text has been unchanged in the help page for 13 years. Duncan Murdoch
Gabor Grothendieck
2023-Dec-29 18:45 UTC
[Rd] eval(parse()) within mutate() returning same value for all rows
If the question is how to accomplish this as opposed to how to use eval then we can do it without eval like this provided we can assume that words contains three %s . library(dplyr) library(tidyr) df <- tibble(words=c("%s plus %s equals %s"),args=c("1,1,2","2,2,4","3,3,6")) df |> separate_wider_delim(args, ",", names = c("a", "b", "c")) |> mutate(combined = sprintf(words, a, b, c)) ## # A tibble: 3 ? 5 ## words a b c combined ## <chr> <chr> <chr> <chr> <chr> ## 1 %s plus %s equals %s 1 1 2 1 plus 1 equals 2 ## 2 %s plus %s equals %s 2 2 4 2 plus 2 equals 4 ## 3 %s plus %s equals %s 3 3 6 3 plus 3 equals 6 On Fri, Dec 29, 2023 at 9:14?AM Mateo Obreg?n <obregonmateo at gmail.com> wrote:> > Hi all- > > Looking through stackoverflow for R string combining examples, I found the > following from 3 years ago: > > <https://stackoverflow.com/questions/63881854/how-to-format-strings-using-values-from-other-column-in-r> > > The top answer suggests to use eval(parse(sprintf())). I tried the suggestion > and it did not return the expected combines strings. I thought that this might > be an issue with some leftover values being reused, so I explicitly eval() > with a new.env(): > > > library(dplyr) > > df <- tibble(words=c("%s plus %s equals %s"), > args=c("1,1,2","2,2,4","3,3,6")) > > df |> mutate(combined = eval(parse(text=sprintf("sprintf('%s', %s)", words, > args)), envir=new.env())) > > # A tibble: 3 ? 3 > words args combined > <chr> <chr> <chr> > 1 %s plus %s equals %s 1,1,2 3 plus 3 equals 6 > 2 %s plus %s equals %s 2,2,4 3 plus 3 equals 6 > 3 %s plus %s equals %s 3,3,6 3 plus 3 equals 6 > > The `combined` is not what I was expecting, as the same last eval() is > returned for all three rows. > > Am I missing something? What has changed in the past three years? > > Mateo. > -- > Mateo Obreg?n > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com