Search code examples
rdataframemagrittrnse

Writing non-standard evaluation syntax with use of magrittr reverse pipe


I'm looking at simple way of simplifying code.

Example

The sqrt function could be easily applied to the subset of columns below.

require(magrittr)
mtcars[,-which(colnames(mtcars) %in% 
                 c("mpg", "cyl", "drat", "wt", "carb",
                   "hp", "qsec", "vs", "am", "gear"))] %<>%
  sqrt

Problem

I'm interested in applying other transformations to the subset without the need to type the whole subsetting sequence again.

For instance the code:

mtcars[,-which(colnames(mtcars) %in% 
                 c("mpg", "cyl", "drat", "wt", "carb",
                   "hp", "qsec", "vs", "am", "gear"))] %<>%
  .data * 1000

will return error:

Error in function_list[[k]](value) : could not find function ".data"

Same with syntax using .. My question is: syntax-wise, how can i get the same effect as in the sqrt function but applying longer function to the passed subset?


Solution

  • What about?

    sel_cols <- setdiff(colnames(mtcars), 
                        c("mpg", "cyl", "drat", "wt", "carb",
                          "hp", "qsec", "vs", "am", "gear"))
    mtcars[, sel_cols] %<>% {sqrt(.) %>% `*`(1000)}
    

    Or a data.table approach?

    library(data.table)
    sel_cols <- setdiff(colnames(mtcars), 
                        c("mpg", "cyl", "drat", "wt", "carb",
                          "hp", "qsec", "vs", "am", "gear"))
    
    dt <- as.data.table(mtcars)
    dt[, (sel_cols) := lapply(.SD, sqrt), .SDcols = sel_cols][]
    

    and combined with pipe:

    dt <- as.data.table(mtcars)
    dt[, (sel_cols) := lapply(.SD, function(x) {sqrt(x) %>% `*`(1000)}), .SDcols = sel_cols][]