Reputation: 1459
I have a variable in a data frame that contains integers and some "<31" values. R recognizes this variable as a factor.
I'd like to set the <31 values to 30, but I've been unable to find an approach to do this.
#example my approach so far
a <- factor(c("31","32","43","36","35","46","<31"))
df <- as.data.frame(a)
str(df)
mutate(df, b = as.numeric(if_else(a == "<31", 30, a)))
Error: `false` must be a double vector, not a `factor` object
Help would be appreciated.
Upvotes: 0
Views: 575
Reputation: 76450
The problem is in if_else
being more strict than base R ifelse
. From help("if_else")
:
Description
Compared to the base ifelse(), this function is more strict. It checks that true and false are the same type. This strictness makes the output type more predictable, and makes it somewhat faster.
And in section Arguments:
true, false
Values to use forTRUE
andFALSE
values of condition. They must be either the same length as condition, or length 1. They must also be the same type:if_else()
checks that they have the same type and same class. All other attributes are taken from true.
So in order to the mutate
instruction in the question work, coerce both true and false to the same class.
As a side note, I will recreate the data set since there is no need for as.data.frame
, the correct way is to use data.frame
.
library(dplyr)
a <- factor(c("31","32","43","36","35","46","<31"))
df <- data.frame(a)
mutate(df, b = as.numeric(if_else(a == "<31", "30", as.character(a))))
# a b
#1 31 31
#2 32 32
#3 43 43
#4 36 36
#5 35 35
#6 46 46
#7 <31 30
Upvotes: 2
Reputation: 388982
You can use fct_recode
from forcats
and then convert it to numeric.
library(dplyr)
df %>%
mutate(b = forcats::fct_recode(a, `30` = "<31"),
b = as.numeric(as.character(b)))
# a b
#1 31 31
#2 32 32
#3 43 43
#4 36 36
#5 35 35
#6 46 46
#7 <31 30
Upvotes: 2