4

I was trying to chain ifelse statement in one of my R function. Basically what I want to do is:

do.something <- function (df, cond=TRUE){
    df %>% ifelse(cond, do something, do something else)
}

Use mtcars dataset as an example:

    select.vars <- function (df, cond=TRUE){
        df %>% ifelse(cond, select(., mpg,wt), select(., hp, wt))
    }

    select.vars(mtcars )

The error message:

Error in ifelse(., cond, select(., mpg, wt), select(., hp, wt)) : unused argument (select(., hp, wt))

I just wonder what I did wrong. Any one can help? Thanks a lot.

zesla
  • 11,155
  • 16
  • 82
  • 147
  • 1
    Possible duplicate of [R Conditional evaluation when using the pipe operator %>%](https://stackoverflow.com/questions/30604107/r-conditional-evaluation-when-using-the-pipe-operator) – HubertL Jul 26 '17 at 19:52
  • Yeah, purrr::when (in HubertL's link) is the idiomatic way, I guess. That's what I was pointed towards when I asked a similar question https://github.com/tidyverse/magrittr/issues/91 – Frank Jul 26 '17 at 19:55

2 Answers2

4

As the logical vector is of length 1, we can use an if/else condition

select.vars <- function (df, cond=TRUE){
    if(cond){
       df %>%
           select(mpg, wt)
    } else {
       df %>%
           select(hp, wt)
 }
}

select.vars(mtcars )

It is better to use if/else for this purpose, but if we need ifelse and option would be to use ifelse within the select

select.vars <- function (df, cond=TRUE){

      df %>%
         select(ifelse(rep(cond, 2), c('mpg', 'wt'), c('hp', 'wt')))     


 }

select.vars(mtcars)
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thanks. I know how to do it with if/else condition. Just wonder if there is anyway to chain the ifelse, so that I can keep chaining other operation... – zesla Jul 26 '17 at 19:37
  • thanks. that works. A follow-up question. what if the number of variables I want to select are different for the two conditions? – zesla Jul 26 '17 at 20:15
  • @zesla This is the reason I would opt for the `if/else` because `ifelse` needs the length to be the same for all the arguments – akrun Jul 27 '17 at 02:17
1

You can use if enclosed in brackets:

select.vars <- function (df, cond=TRUE){
  df %>% {`if`(cond, select(., mpg,wt), select(., hp, wt))}
}
select.vars(mtcars )
                     mpg    wt
Mazda RX4           21.0 2.620
Mazda RX4 Wag       21.0 2.875
Datsun 710          22.8 2.320
Hornet 4 Drive      21.4 3.215
Hornet Sportabout   18.7 3.440
Valiant             18.1 3.460
Duster 360          14.3 3.570
Merc 240D           24.4 3.190
Merc 230            22.8 3.150
Merc 280            19.2 3.440
Merc 280C           17.8 3.440
Merc 450SE          16.4 4.070
Merc 450SL          17.3 3.730
Merc 450SLC         15.2 3.780
Cadillac Fleetwood  10.4 5.250
Lincoln Continental 10.4 5.424
Chrysler Imperial   14.7 5.345
Fiat 128            32.4 2.200
Honda Civic         30.4 1.615
Toyota Corolla      33.9 1.835
Toyota Corona       21.5 2.465
Dodge Challenger    15.5 3.520
AMC Javelin         15.2 3.435
Camaro Z28          13.3 3.840
Pontiac Firebird    19.2 3.845
Fiat X1-9           27.3 1.935
Porsche 914-2       26.0 2.140
Lotus Europa        30.4 1.513
Ford Pantera L      15.8 3.170
Ferrari Dino        19.7 2.770
Maserati Bora       15.0 3.570
Volvo 142E          21.4 2.780
HubertL
  • 19,246
  • 3
  • 32
  • 51