tidyverse / dtplyr

Data table backend for dplyr
https://dtplyr.tidyverse.org
Other
670 stars 57 forks source link

`str_glue` does not recognize tibble columns as variables when translated #344

Closed orgadish closed 2 years ago

orgadish commented 2 years ago

Using str_glue with tibble column names as variables does not seem to work with dtplyr::lazy_dt, unless they are passed in as args rather than directly in string.

dtplyr 1.2.1 dplyr 1.0.7 stringr 1.4.0

library(tidyverse)
library(dtplyr)

starwars %>% 
  transmute(
    name_height_mass = str_glue("{name} ({height} cm,  {mass} kg)")
  )
#> # A tibble: 87 × 1
#>    name_height_mass                   
#>    <glue>                             
#>  1 Luke Skywalker (172 cm,  77 kg)    
#>  2 C-3PO (167 cm,  75 kg)             
#>  3 R2-D2 (96 cm,  32 kg)              
#>  4 Darth Vader (202 cm,  136 kg)      
#>  5 Leia Organa (150 cm,  49 kg)       
#>  6 Owen Lars (178 cm,  120 kg)        
#>  7 Beru Whitesun lars (165 cm,  75 kg)
#>  8 R5-D4 (97 cm,  32 kg)              
#>  9 Biggs Darklighter (183 cm,  84 kg) 
#> 10 Obi-Wan Kenobi (182 cm,  77 kg)    
#> # … with 77 more rows

starwars %>% 
  lazy_dt() %>% 
  transmute(
    name_height_mass = str_glue("{name} ({height} cm,  {mass} kg)")
  ) %>% 
  as_tibble()
#> Error in eval(parse(text = text, keep.source = FALSE), envir): object 'name' not found

starwars %>% 
  lazy_dt() %>% 
  transmute(
    name_height_mass = str_glue("{a} ({b} cm,  {c} kg)", a=name, b=height, c=mass)
  ) %>% 
  as_tibble()
#> # A tibble: 87 × 1
#>    name_height_mass                   
#>    <glue>                             
#>  1 Luke Skywalker (172 cm,  77 kg)    
#>  2 C-3PO (167 cm,  75 kg)             
#>  3 R2-D2 (96 cm,  32 kg)              
#>  4 Darth Vader (202 cm,  136 kg)      
#>  5 Leia Organa (150 cm,  49 kg)       
#>  6 Owen Lars (178 cm,  120 kg)        
#>  7 Beru Whitesun lars (165 cm,  75 kg)
#>  8 R5-D4 (97 cm,  32 kg)              
#>  9 Biggs Darklighter (183 cm,  84 kg) 
#> 10 Obi-Wan Kenobi (182 cm,  77 kg)    
#> # … with 77 more rows

Created on 2022-02-14 by the reprex package (v2.0.1)

markfairbanks commented 2 years ago

This is actually caused by a data.table issue.

For now one way to work around this is to specify an evaluation environment with .SD in str_glue() or to use .SD with str_glue_data(). FYI - .SD is a special symbol in data.table that stands for "subset of data".

library(dtplyr)
library(dplyr, warn.conflicts = FALSE)
library(stringr)

starwars %>% 
  lazy_dt() %>% 
  transmute(
    name_height_mass1 = str_glue("{name} ({height} cm,  {mass} kg)", .envir = .SD),
    name_height_mass2 = str_glue_data(.SD, "{name} ({height} cm,  {mass} kg)")
  ) %>% 
  as_tibble()
#> # A tibble: 87 × 2
#>    name_height_mass1                   name_height_mass2                  
#>    <glue>                              <glue>                             
#>  1 Luke Skywalker (172 cm,  77 kg)     Luke Skywalker (172 cm,  77 kg)    
#>  2 C-3PO (167 cm,  75 kg)              C-3PO (167 cm,  75 kg)             
#>  3 R2-D2 (96 cm,  32 kg)               R2-D2 (96 cm,  32 kg)              
#>  4 Darth Vader (202 cm,  136 kg)       Darth Vader (202 cm,  136 kg)      
#>  5 Leia Organa (150 cm,  49 kg)        Leia Organa (150 cm,  49 kg)       
#>  6 Owen Lars (178 cm,  120 kg)         Owen Lars (178 cm,  120 kg)        
#>  7 Beru Whitesun lars (165 cm,  75 kg) Beru Whitesun lars (165 cm,  75 kg)
#>  8 R5-D4 (97 cm,  32 kg)               R5-D4 (97 cm,  32 kg)              
#>  9 Biggs Darklighter (183 cm,  84 kg)  Biggs Darklighter (183 cm,  84 kg) 
#> 10 Obi-Wan Kenobi (182 cm,  77 kg)     Obi-Wan Kenobi (182 cm,  77 kg)    
#> # … with 77 more rows
markfairbanks commented 2 years ago

@orgadish - all set.

# devtools::install_github("tidyverse/dtplyr")
library(tidyverse)
library(dtplyr)

starwars %>%
  lazy_dt() %>%
  transmute(
    name_height_mass = str_glue("{name} ({height} cm,  {mass} kg)")
  )
#> Source: local data table [87 x 1]
#> Call:   `_DT1`[, .(name_height_mass = str_glue("{name} ({height} cm,  {mass} kg)", 
#>     .envir = .SD))]
#> 
#>   name_height_mass               
#>   <glue>                         
#> 1 Luke Skywalker (172 cm,  77 kg)
#> 2 C-3PO (167 cm,  75 kg)         
#> 3 R2-D2 (96 cm,  32 kg)          
#> 4 Darth Vader (202 cm,  136 kg)  
#> 5 Leia Organa (150 cm,  49 kg)   
#> 6 Owen Lars (178 cm,  120 kg)    
#> # … with 81 more rows
#> 
#> # Use as.data.table()/as.data.frame()/as_tibble() to access results