3

I want to transform factor to numeric to be able to take the mean of it as.numeric changes the value, numeric doesn't work.

mtcars$vec <- factor(c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
                                1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1))

        num.cols <- c("vec" ) 
        mtcars[num.cols] <- lapply(mtcars[num.cols], as.numeric) 
        str(mtcars)

        mtcars$vec

expected results should be numeric and consist of only 0 and 1

mtcars$vec
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

many thanks in advance

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
Seyma Kalay
  • 2,037
  • 10
  • 22

1 Answers1

4

We need to convert to character and then to numeric because if we directly apply as.numeric, it gets coerced to the integer storage values instead of the actual values which starts from 1. In this case, there is a confusion because the values are binary

mtcars[num.cols] <-  lapply(mtcars[num.cols], 
              function(x) as.numeric(as.character(x))) 
mtcars$vec
#[1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Or a faster option is also

mtcars[num.cols] <- lapply(mtcars[num.cols],  function(x) as.numeric(levels(x)[x]))

If it is a single column, we can do this more easily

mtcars[[num.cols]] <- as.numeric(levels(mtcars[[num.cols]])[mtcars[[num.cols]]])

As an example

v1 <- factor(c(15, 15, 3, 3))
as.numeric(v1)
#[1] 2 2 1 1

as.numeric(as.character(v1))
#[1] 15 15  3  3
akrun
  • 874,273
  • 37
  • 540
  • 662