I spent 45 mins to get a very simple if()
inside a loop to work, but I want to understand why it was failing in the first place.
It's a simple R Magrittr pipe chain with a if()
condition in braces {}
Here's the simplified reprex (reproducible example)
library(tidyverse) # load tidyverse library
a <- tibble(a1 = 1:6, a2 = 6:1, a3 = rep(c('a', 'b'),3), a4 = as_factor(5:10))
# function to check the data type of a column
# Fails
check1 <- function(.df, .colm)
{
.df %>%
{ if(. %>% pull(var = {{.colm}}) %>% is.character()) 1 else 2} # pull .colm from .df and check if is char
}
# Works
check2 <- function(.df, .colm)
{
.df %>%
{if(pull(., var = {{.colm}}) %>% is.character()) 1 else 2} # pull .colm from .df and check if is char
}
check1(a, a1) # Fails
#> Error in if (. %>% pull(var = {: argument is not interpretable as logical
check2(a, a1) # Works
#> [1] 2
Created on 2021-03-30 by the reprex package (v0.3.0)
Also do let me know if there's a simpler way to check the class()
of a column in a data frame that can be generalized to have the column name taken from user input to a funtion
There are two problems:
both the calls to check1 and check2 give errors because their inputs have not been defined
a magrittr pipeline that begins with just a dot on the left hand side defines a function so in the first case the part within the condition portion of the if
is defining a function, not a logical condition.
library(magrittr)
f <- . %>% { . ^ 2 }
f(3)
## [1] 9
This fails for the same reason
library(purrr)
library(dplyr)
BOD %>% { if (. %>% pull("demand") %>% is.numeric) 1 else 0 }
but this works since the left hand side is now (.) instead of just .
BOD %>% { if ( (.) %>% pull("demand") %>% is.numeric) 1 else 0 }