WinVector / wrapr

Wrap R for Sweet R Code
https://winvector.github.io/wrapr/
Other
136 stars 11 forks source link

Invalid names in alias values #4

Closed dtelad11 closed 6 years ago

dtelad11 commented 6 years ago

I'm writing a script where all operations are done over a user-supplied CSV. The column names might not be standard -- most often, a column might begin with a number (such as "4GS"). At one point I iterate over the columns with wrapr::let:

lapply(colnames(df), function(col_name) {
  wrapr::let(
    alias = list(COL_NAME = col_name),
    exprs = {
      df %>%
        dplyr::group_by(COL_NAME)
        .
        .
        .
    }
  )
})

Which leads to an "alias value not a valid name".

I understand that this is part of the wrap::let design philosophy (*let deliberately checks that it is mapping only to legal R names; this is to discourage the use of let to make names to arbitrary values, as that is the more properly left to R's environment systems). Do you have any plans to change that philosophy and allow invalid names? Alternatively, could you recommend another approach to dealing with this data?

Thank you!

JohnMount commented 6 years ago

Thanks for the issue report, feedback and user opinions are very important to me.

I definitely understand that developer prejudices (mine) come at some cost of user flexibility (i,e., they are not free- somebody pays). But roughly they are there to try and keep maintenance costs down. Enough users disagree with me and I will likely change things (or at the very least make the desired calling conventions available as easy alternatives).

That being said: your use case is, of course, a legitimate one.

The following code should do what you want:

suppressPackageStartupMessages(library("dplyr"))
library("wrapr")

df <- data.frame(x=1)
colnames(df) = "4G"

lapply(colnames(df), function(col_name) {
  wrapr::let(
    alias = list(COL_NAME = col_name),
    expr = {
      df %>%
        dplyr::group_by(COL_NAME)
    },
    strict = FALSE)
})
#> [[1]]
#> # A tibble: 1 x 1
#> # Groups: 4G [1]
#>    `4G`
#>   <dbl>
#> 1  1.00

Our idea is: once you set strict = FALSE we will try to do what you specify.

Also you might want to try out our new mapsyms notation, which would let us write the above code as follows:

lapply(colnames(df), function(COL_NAME) {
  wrapr::let(
    alias = mapsyms(COL_NAME),
    expr = {
      df %>%
        dplyr::group_by(COL_NAME)
    },
    strict = FALSE)
})

The above is explained in our "let X=X" article.