0

Assuming the following dataframe df:

df <- structure(list(`week1` = structure(c(number = 4L, 
area1 = 1L, area2 = 2L, price1 = 3L, 
price2 = 5L), .Label = c("154.93", "304.69", "3554.50", 
"49", "7587.22"), class = "factor"), `week2` = structure(c(number = 3L, 
area1 = 1L, area2 = 4L, price1 = 2L, 
price2 = 5L), .Label = c("28.12", "2882.91", "30", 
"44.24", "4534.47"), class = "factor")), class = "data.frame", row.names = c("number", 
"area1", "area2", "price1", 
"price2"))

I'm try to convert its week1 and week2 columns from factor to numeric with:

cols = c(1, 2)
df[, cols] <- as.numeric(as.character(df[, cols]))
# df[cols] <- lapply(df[cols], as.numeric) # gives incorrect results

Out:

enter image description here

But it returns NAs or incorrect results for those columns. However, the following code gives right answer:

cols = c(1, 2)   
df[, cols] = apply(df[, cols], 2, function(x) as.numeric(as.character(x)))
df 

Out:

enter image description here

Why did I get NAs with the first solution which works for this case? Thanks.

ah bon
  • 9,293
  • 12
  • 65
  • 148

1 Answers1

1

as.character/as.numeric expects a vector as input. With df[, cols] you are passing a dataframe to it (check class(df[, cols])).

If you are talking about the accepted answer in the link it says to change the code in for loop and doesn't suggest to pass entire dataframe. To change class of multiple columns you can use for loop, apply or lapply.

df[cols] <- lapply(df[cols], function(x) as.numeric(as.character(x)))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • Thanks, could you pls explain what `2` represent in `apply(df[, cols], 2, function(x) as.numeric(as.character(x)))`? – ah bon Jan 22 '21 at 06:37
  • 1
    2 is to apply a function column-wise, 1 is for row-wise. Check `?apply`. – Ronak Shah Jan 22 '21 at 06:38
  • If I want to convert one row by its name from `float` to `integer`, I used `lapply(df['number', ], function(x) as.integer(x))` but not working, could you help? Which `function` should I choose? – ah bon Jan 22 '21 at 11:12
  • 1
    You cannot convert one row to any class. In R, one column can have only one class. So you can either have integer or numeric column. You cannot have different classes in one column. – Ronak Shah Jan 22 '21 at 12:17