strange behaviour logical OR operator (| ||) in R

dplyr
base-r

#1

I am confused by the | and || operator's behavior. Look the code below, I think p1|p2 and p1||p2 should be same, but p1||p2 is different.

library(magrittr)
df <- data.frame(x = 1:4, img = c("a.jpg", "b.jpg", "", NA))

FALSE || TRUE
#> [1] TRUE
NA || TRUE
#> [1] TRUE

fix_image_link <- function(df,
                           df_image_url_col_name,
                           image_url_prefix = NULL) {
  col_name <- rlang::ensym(df_image_url_col_name)
  df %>%
    dplyr::mutate(
      p1 = is.na(!!col_name),
      p2 = stringi::stri_length(!!col_name) == 0,
      `p1|p2` = is.na(!!col_name) | stringi::stri_length(!!col_name) == 0,
      new_col1 = dplyr::case_when(
        is.na(!!col_name) | stringi::stri_length(!!col_name) == 0  ~ NA_character_,
        TRUE ~ paste0(image_url_prefix,!!col_name)
      ),
      `p1||p2` = is.na(!!col_name) || stringi::stri_length(!!col_name) == 0,
      new_col12 := dplyr::case_when(
      is.na(!!col_name) || stringi::stri_length(!!col_name) == 0  ~ NA_character_,
      TRUE ~ paste0(image_url_prefix,!!col_name)
    ))
}


fix_custom_image_link <- function(df, df_image_url_col_name) {
  col_name <- rlang::ensym(df_image_url_col_name)
  fix_image_link(df = df,
                       df_image_url_col_name = !!col_name,
                       image_url_prefix = "http://picture-server.com")
}

fix_custom_image_link(df, "img")
#>   x   img    p1    p2 p1|p2                       new_col1 p1||p2
#> 1 1 a.jpg FALSE FALSE FALSE http://picture-server.coma.jpg  FALSE
#> 2 2 b.jpg FALSE FALSE FALSE http://picture-server.comb.jpg  FALSE
#> 3 3       FALSE  TRUE  TRUE                           <NA>  FALSE
#> 4 4  <NA>  TRUE    NA  TRUE                           <NA>  FALSE
#>                        new_col12
#> 1 http://picture-server.coma.jpg
#> 2 http://picture-server.comb.jpg
#> 3      http://picture-server.com
#> 4    http://picture-server.comNA

Created on 2018-11-30 by the reprex package (v0.2.1)

Session info
devtools::session_info()
#> Warning in system("timedatectl", intern = TRUE): running command
#> 'timedatectl' had status 1
#> ─ Session info ──────────────────────────────────────────────────────────
#>  setting  value                       
#>  version  R version 3.5.1 (2018-07-02)
#>  os       Debian GNU/Linux 9 (stretch)
#>  system   x86_64, linux-gnu           
#>  ui       X11                         
#>  language (EN)                        
#>  collate  en_US.UTF-8                 
#>  ctype    en_US.UTF-8                 
#>  tz       Etc/UTC                     
#>  date     2018-11-30                  
#> 
#> ─ Packages ──────────────────────────────────────────────────────────────
#>  package     * version    date       lib source                      
#>  assertthat    0.2.0      2017-04-11 [1] CRAN (R 3.5.1)              
#>  backports     1.1.2      2017-12-13 [1] CRAN (R 3.5.1)              
#>  base64enc     0.1-3      2015-07-28 [1] CRAN (R 3.5.1)              
#>  bindr         0.1.1      2018-03-13 [1] CRAN (R 3.5.1)              
#>  bindrcpp    * 0.2.2      2018-03-29 [1] CRAN (R 3.5.1)              
#>  callr         3.0.0      2018-08-24 [1] CRAN (R 3.5.1)              
#>  cli           1.0.1      2018-09-25 [1] CRAN (R 3.5.1)              
#>  crayon        1.3.4      2017-09-16 [1] CRAN (R 3.5.1)              
#>  desc          1.2.0      2018-05-01 [1] CRAN (R 3.5.1)              
#>  devtools      2.0.1      2018-10-26 [1] CRAN (R 3.5.1)              
#>  digest        0.6.18     2018-10-10 [1] CRAN (R 3.5.1)              
#>  dplyr         0.7.8      2018-11-10 [1] CRAN (R 3.5.1)              
#>  evaluate      0.12       2018-10-09 [1] CRAN (R 3.5.1)              
#>  fs            1.2.6      2018-08-23 [1] CRAN (R 3.5.1)              
#>  glue          1.3.0      2018-07-17 [1] CRAN (R 3.5.1)              
#>  htmltools     0.3.6      2017-04-28 [1] CRAN (R 3.5.1)              
#>  knitr         1.20       2018-02-20 [1] CRAN (R 3.5.1)              
#>  magrittr    * 1.5        2014-11-22 [1] CRAN (R 3.5.1)              
#>  memoise       1.1.0      2017-04-21 [1] CRAN (R 3.5.1)              
#>  pillar        1.3.0      2018-07-14 [1] CRAN (R 3.5.1)              
#>  pkgbuild      1.0.2      2018-10-16 [1] CRAN (R 3.5.1)              
#>  pkgconfig     2.0.2      2018-08-16 [1] CRAN (R 3.5.1)              
#>  pkgload       1.0.2      2018-10-29 [1] CRAN (R 3.5.1)              
#>  prettyunits   1.0.2      2015-07-13 [1] CRAN (R 3.5.1)              
#>  processx      3.2.0      2018-08-16 [1] CRAN (R 3.5.1)              
#>  ps            1.2.1      2018-11-06 [1] CRAN (R 3.5.1)              
#>  purrr         0.2.5      2018-05-29 [1] CRAN (R 3.5.1)              
#>  R6            2.3.0      2018-10-04 [1] CRAN (R 3.5.1)              
#>  Rcpp          1.0.0      2018-11-07 [1] CRAN (R 3.5.1)              
#>  remotes       2.0.2      2018-10-30 [1] CRAN (R 3.5.1)              
#>  rlang         0.3.0.9000 2018-11-28 [1] Github (r-lib/rlang@cd272fd)
#>  rmarkdown     1.10       2018-06-11 [1] CRAN (R 3.5.1)              
#>  rprojroot     1.3-2      2018-01-03 [1] CRAN (R 3.5.1)              
#>  sessioninfo   1.1.1      2018-11-05 [1] CRAN (R 3.5.1)              
#>  stringi       1.2.4      2018-07-20 [1] CRAN (R 3.5.1)              
#>  stringr       1.3.1      2018-05-10 [1] CRAN (R 3.5.1)              
#>  testthat      2.0.1      2018-10-13 [1] CRAN (R 3.5.1)              
#>  tibble        1.4.2      2018-01-22 [1] CRAN (R 3.5.1)              
#>  tidyselect    0.2.5      2018-10-11 [1] CRAN (R 3.5.1)              
#>  usethis       1.4.0      2018-08-14 [1] CRAN (R 3.5.1)              
#>  withr         2.1.2      2018-03-15 [1] CRAN (R 3.5.1)              
#>  yaml          2.2.0      2018-07-25 [1] CRAN (R 3.5.1)              
#> 
#> [1] /usr/local/lib/R/site-library
#> [2] /usr/local/lib/R/library

#2

from logic{base}

& and && indicate logical AND and | and || indicate logical OR. The shorter form performs elementwise comparisons in much the same way as arithmetic operators. The longer form evaluates left to right examining only the first element of each vector. Evaluation proceeds only until the result is determined. The longer form is appropriate for programming control-flow and typically preferred in if clauses.

It's a subtle difference between the two forms


#3

Thanks. I know the difference exists before but I didn't realize that it applies to dplyr's verbs as well. It's intuitively to think dplyr::mutate evaluates results element by element.


#4

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.