Reputation: 4441
Given this factor variable:
library(tidyverse)
a <- factor(c(1,1,1,2,2), levels=c(1,2), labels=c("Male", "Female"))
I want this to error out because Females
is not a valid level:
a %>% .[.=="Male"|.=="Females"]
How can I do that?
Upvotes: 2
Views: 62
Reputation: 19484
Adding a line involving stopifnot
before that command will invoke an error - if that's what you're after.
{
stopifnot(any(levels(a) %in% "Females"))
a %>% .[.=="Male"|.=="Females"]
}
Or make it a bit more general:
{
a1 <- "Male"
a2 <- "Females"
stopifnot("Error. Invalid factor level." = all(c(a1, a2) %in% levels(a)))
a %>% .[.==a1|.==a2]
}
Upvotes: 1
Reputation: 34751
forcats::fct_match()
errors when levels aren't present, so you can do:
library(forcats)
a <- factor(c(1,1,1,2,2), levels=c(1,2), labels=c("Male", "Female"))
a %>% .[fct_match(., c("Male", "Females"))]
#> Error in `fct_match()`:
#> ! All `lvls` must be present in `f`.
#> ℹ Missing levels: "Females"
a %>% .[fct_match(., c("Male", "Female"))]
#> [1] Male Male Male Female Female
#> Levels: Male Female
Upvotes: 4
Reputation: 132969
You could trace Ops.factor
:
trace(Ops.factor, tracer = quote({
if (nzchar(.Method[1L])) stopifnot("Comparing factor with value not in levels" =
all(e2 %in% levels(e1)))
if (nzchar(.Method[2L])) stopifnot("Comparing factor with value not in levels" =
all(e1 %in% levels(e2)))
}), at = 1, print = FALSE)
#Tracing function "Ops.factor" in package "base"
"Females" == a
#Error in Ops.factor("Females", a) :
# Comparing factor with value not in levels
"Female" == a
#[1] FALSE FALSE FALSE TRUE TRUE
untrace(Ops.factor)
PS: I would want to test the tracer with some edge cases if I intended to use it in production code.
Upvotes: 3