[Rd] eval(parse()) within mutate() returning same value for all rows
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Fri Dec 29 18:22:47 CET 2023
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
More information about the R-devel
mailing list