Error using special character with reprex::reprex()

Viewed 139

I found out that reprex::reprex can't read the ¦ character (and some other special character like "é") and throws an error. Is there a way to have reprex work with the local encoding (here French locale) ?

Reprex

reprex::reprex(x = {
    tibble::tribble(
        ~var1,          ~var2, ~var3,
        "gr¦pefruit",   "ugli fruit",    4L,
        "huckleberry",      "kumquat",    6L,
        "duri¦n", "blackcurrant",    1L,
        "d¦te",   "cantaloup¦",    1L,
        "fig", "canary m¦lon",    6L,
        "s¦l¦l berry",     "rambutan",    5L
    )
})

Output in Viewer pane

``` r
tibble::tribble(
    ~var1,          ~var2, ~var3,
    "gr


---
title: reprex_reprex.R
author: cbo
date: '2020-11-08'

---
#> Error: <text>:3:9: INCOMPLETE_STRING inattendu(e)
#> 10: 
#> 11: ---
#>             ^

Session Info

R version 4.0.2 (2020-06-22)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=French_France.1252  LC_CTYPE=French_France.1252   
[3] LC_MONETARY=French_France.1252 LC_NUMERIC=C                  
[5] LC_TIME=French_France.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

loaded via a namespace (and not attached):
 [1] pillar_1.4.6      compiler_4.0.2    prettyunits_1.1.1
 [4] remotes_2.1.1     tools_4.0.2       testthat_2.3.2   
 [7] digest_0.6.25     pkgbuild_1.1.0    pkgload_1.1.0    
[10] evaluate_0.14     memoise_1.1.0     lifecycle_0.2.0  
[13] tibble_3.0.3      pkgconfig_2.0.3   rlang_0.4.7      
[16] reprex_0.3.0      cli_2.0.2         rstudioapi_0.11  
[19] yaml_2.2.1        blogdown_0.20.2   xfun_0.15        
[22] stringr_1.4.0     withr_2.2.0       knitr_1.29       
[25] desc_1.2.0        fs_1.4.2          vctrs_0.3.2      
[28] devtools_2.3.0    rprojroot_1.3-2   glue_1.4.1       
[31] R6_2.4.1          processx_3.4.3    fansi_0.4.1      
[34] rmarkdown_2.3     bookdown_0.20     sessioninfo_1.1.1
[37] whisker_0.4       callr_3.4.3       clipr_0.7.0      
[40] magrittr_1.5      backports_1.1.7   ps_1.3.3         
[43] ellipsis_0.3.1    htmltools_0.5.0   usethis_1.6.1    
[46] assertthat_0.2.1  utf8_1.1.4        stringi_1.4.6    
[49] crayon_1.3.4 

Update with polkas' suggestion

Both locale = c("LC_COLLATE" = "French_France.1252") and locale = c("LC_COLLATE" = "fr_LU.UTF-8") have been tried with the following error result :

code

reprex_locale(x = {
    tibble::tribble(
        ~var1,          ~var2, ~var3,
        "gr¦pefruit",   "ugli fruit",    4L,
        "huckleberry",      "kumquat",    6L,
        "duri¦n", "blackcurrant",    1L,
        "d¦te",   "cantaloup¦",    1L,
        "fig", "canary m¦lon",    6L,
        "s¦l¦l berry",     "rambutan",    5L
    )}, language = "fr",
    locale = c("LC_COLLATE" = "fr_LU.UTF-8")
)

console

 Error : callr subprocess failed: <text>:28:1: ')' unexpected
27:         locale = c("LC_COLLATE" = "fr_LU.UTF-8")
28: )
    ^

Solution used - for those that may come next

TL;DR : the error is restricted to OS Windows with reprex 0.3.0 so installing the dev version fixed the issue :

devtools::install_github("tidyverse/reprex")

The why it happened : as mentionned by @cderv and nicely explained in the attached blog post R in Windows tends to use locale encoding as intermediary step when writing a file. Thus when you use writeLines() with R-Windows it will mess up the special characters unless you specify no intermediary step and the use of bytes all along with writeLines(..., usebytes = "TRUE").

3 Answers

I think this is due to how windows and encoding is working. By default windows is not UTF8 and you have special character I believe that requires this encoded.

Sometimes the behavior is tricky because R will use default encoding which is native and this can give unexpected result because it will convert to native before writing to file. See this great post about it: https://kevinushey.github.io/blog/2018/02/21/string-encoding-and-r/

For getting this to work, I would

  • write the code to reprex in a R file, encoded in UTF8
tibble::tribble(
  ~var1,          ~var2, ~var3,
  "gr¦pefruit",   "ugli fruit",    4L,
  "huckleberry",      "kumquat",    6L,
  "duri¦n", "blackcurrant",    1L,
  "d¦te",   "cantaloup¦",    1L,
  "fig", "canary m¦lon",    6L,
  "s¦l¦l berry",     "rambutan",    5L
)
  • Then use reprex on this file
reprex::reprex(input = "test.R")

This works for me.

There may be an issue in reprex about how it is writing to file on Windows when you provide code directly in reprex::reprex()

It is hard to reproduce your environment even with withr package. In my environment it always works correctly.

This solution from tidyverse might work https://github.com/tidyverse/reprex/blob/master/R/reprex-locale.R:

reprex_locale <- function(...,
                          language = "en",
                          locale = NULL) {
  withr::local_envvar(c(LANGUAGE = language))
  if (!is.null(locale)) {
    # If we use withr::local_locale(), the new locale is NOT inherited by the
    # reprexing child process. Whereas it is if we use an env var approach.
    withr::local_envvar(locale)
  }
  reprex(...)
}

I understand that reprex_locale with language = "fr" and certain locale could work for you.

I have found this work around for Windows and current reprex CRAN version (0.3.0) with the ANSI character code \xa6 for ¦ :

reprex::reprex(x = {
    dfr <- tibble::tribble(
        ~var1,          ~var2, ~var3,
        "gr\xa6pefruit",   "ugli fruit",    4L,
        "huckleberry",      "kumquat",    6L,
        "duri\xa6n", "blackcurrant",    1L,
        "d\xa6te",   "cantaloup\xa6",    1L,
        "fig", "canary m\xa6lon",    6L,
        "s\xa6l\xa6l berry",     "rambutan",    5L
    )
Related