hpy
hpy

Reputation: 2161

Can't `relevel` a factor variable in data frame because it is an `integer`, how to fix?

I have a tibble data frame in R called research_fields:

# A tibble: 411 × 2
   Response_ID Field              
         <int> <fct>              
 1           1 Business           
 2           2 Psychology         
 3           3 Medicine and health
 4           4 Other              
 5           5 Medicine and health
 6           6 Education          
 7           7 Public policy      
 8           8 Computer science   
 9           9 Biology            
10          10 Medicine and health
# … with 401 more rows

The Field variable is already a factor, but I want to use forcats::fct_relevel() to move the "Other" factor to be the last, so I tried this:

fct_relevel(research_fields$"Field", "Other", Inf) 

But I get the error:

Error:
! Can't convert a number to a character vector.

I don't understand why because Field is clearly a factor (fct), not an integer. Why is this?

How to I make "Other" come last? Is there a way to do this with mutate() and something else from forcats:: perhaps?

Thank you.

Upvotes: 0

Views: 207

Answers (2)

jay.sf
jay.sf

Reputation: 73782

You might need a better conception of what a "factor" variable is. Let's assume we have this factor variable with the associated levels.

head(df$Field)
# [1] Jan May Jan Sep Oct Apr
# 12 Levels: Apr Aug Dec Feb Jan Jul Jun Mar May Nov ... Sep

An easy thing to do is to create a factor again with arbitrary levels= in the desired order (in this example we want of course the right order of the months).

df$Field <- factor(df$Field, levels=c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", 
                                      "Oct", "Nov", "Dec"))

The variable stays the same, but the levels have changed.

head(df$Field)
# [1] Jan May Jan Sep Oct Apr
# 12 Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct ... Dec

Data:

set.seed(42)
df <- data.frame(Field=factor(month.abb[sample(1:12, 50, replace=TRUE)]))

Upvotes: 1

MrFlick
MrFlick

Reputation: 206586

You need to name the after= parmeter when calling fct_relevel

fct_relevel(research_fields$Field, "Other", after=Inf) 

This is because the function signature is

fct_relevel(.f, ..., after = 0L)

That means that if you don't use after= then all the values you passed get sucked in to the ... and are assumed to be level names and the numeric value for infinity is clearly not a valid level name.

Upvotes: 2

Related Questions