Convert categorical variables to numeric in R

Maybe you're after data.matrix. From the function's description:

Return the matrix obtained by converting all the variables in a data frame to numeric mode and then binding them together as the columns of a matrix. Factors and ordered factors are replaced by their internal codes.

Example:

mydf <- data.frame(A = letters[1:5],
                   B = LETTERS[1:5],
                   C = month.abb[1:5],
                   D = 1:5)
str(mydf)
# 'data.frame': 5 obs. of  4 variables:
#  $ A: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
#  $ B: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5
#  $ C: Factor w/ 5 levels "Apr","Feb","Jan",..: 3 2 4 1 5
#  $ D: int  1 2 3 4 5
data.matrix(mydf)
#      A B C D
# [1,] 1 1 3 1
# [2,] 2 2 2 2
# [3,] 3 3 4 3
# [4,] 4 4 1 4
# [5,] 5 5 5 5

Replace it all at once with:

mydf[] <- data.matrix(mydf)
mydf
#   A B C D
# 1 1 1 3 1
# 2 2 2 2 2
# 3 3 3 4 3
# 4 4 4 1 4
# 5 5 5 5 5

Of course if you have many more column types, you'll have to decide first how you want to deal with them. For instance, there's the concern that if there's a character column, data.matrix would result in a column of NA values, which is correct. However, the correct concern should be "How would you like to deal with character columns?

Here are two options. You can extend the logic similarly for other column types.

mydf <- data.frame(A = letters[1:5],
                   B = LETTERS[1:5],
                   C = month.abb[1:5],
                   D = 1:5)
mydf$E <- state.abb[1:5]
str(mydf)
# 'data.frame': 5 obs. of  5 variables:
#  $ A: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
#  $ B: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5
#  $ C: Factor w/ 5 levels "Apr","Feb","Jan",..: 3 2 4 1 5
#  $ D: int  1 2 3 4 5
#  $ E: chr  "AL" "AK" "AZ" "AR" ...

## You want to convert everything to numeric
data.matrix(data.frame(unclass(mydf))) 
#      A B C D E
# [1,] 1 1 3 1 2
# [2,] 2 2 2 2 1
# [3,] 3 3 4 3 4
# [4,] 4 4 1 4 3
# [5,] 5 5 5 5 5

## You only want to convert factors to numeric
mydf[sapply(mydf, is.factor)] <- data.matrix(mydf[sapply(mydf, is.factor)])
mydf
#   A B C D  E
# 1 1 1 3 1 AL
# 2 2 2 2 2 AK
# 3 3 3 4 3 AZ
# 4 4 4 1 4 AR
# 5 5 5 5 5 CA

You can use unclass() to display numeric values of factor variables :

Type_peau<-as.factor(c("Mixte","Normale","Sèche","Mixte","Normale","Mixte"))
Type_peau
unclass(Type_peau)

To do so on all categorical variables, you can use sapply() :

must_convert<-sapply(M,is.factor)       # logical vector telling if a variable needs to be displayed as numeric
M2<-sapply(M[,must_convert],unclass)    # data.frame of all categorical variables now displayed as numeric
out<-cbind(M[,!must_convert],M2)        # complete data.frame with all variables put together

EDIT : A5C1D2H2I1M1N2O1R2T1's solution works in one step :

out<-data.matrix(M)

It only works if your data.frame doesn't contain any character variable though (otherwise, they'll be put to NA).

Tags:

R