[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