Reputation: 35554
I think this is a simple question but I haven't found a suitable solution. To begin with a set of simplified data :
df <- as.data.frame(matrix(1:20, 5, 4))
str(df)
# 'data.frame': 5 obs. of 4 variables:
# $ V1: int 1 2 3 4 5
# $ V2: int 6 7 8 9 10
# $ V3: int 11 12 13 14 15
# $ V4: int 16 17 18 19 20
We can see that all the classes are the integer. What I wanna achieve is converting the 4 classes to integer, numeric, character, and factor respectively. Of course, I can use
df$V1 <- as.XXX(df$V1)
for each column, but I think it's inefficient.
# 'data.frame': 5 obs. of 4 variables:
# $ V1: int 1 2 3 4 5
# $ V2: num 6 7 8 9 10
# $ V3: chr "11" "12" "13" "14" ...
# $ V4: Factor w/ 5 levels "16","17","18",..: 1 2 3 4 5
I reference @joran's answer in R Assign (or copy) column classes from a data frame to another and run the following code :
myclass <- c("integer", "numeric", "character", "factor")
df.2 <- df
df.2[] <- mapply(FUN = as, df.2, myclass, SIMPLIFY = F)
When I call df.2
, an error appears :
Error in as.character.factor(x) : malformed factor
However, It's okay to call str(df.2)
, and apparently only V1
and V3
reach my request.
str(df.2)
# 'data.frame': 5 obs. of 4 variables:
# $ V1: int 1 2 3 4 5
# $ V2: int 6 7 8 9 10
# $ V3: chr "11" "12" "13" "14" ...
# $ V4:Formal class 'factor' [package "methods"] with 3 slots
# .. ..@ .Data : int 16 17 18 19 20
# .. ..@ levels : chr
# .. ..@ .S3Class: chr "factor"
Why cannot as
function deal with classes numeric
and factor
?
Upvotes: 5
Views: 378
Reputation:
If you don't exclude the for
loop method, try this :
df <- as.data.frame(matrix(1:20, 5, 4))
type <- c("integer", "numeric", "character", "factor")
for(i in 1:ncol(df)){
call <- paste("as", type[i], sep = ".")
df[[i]] <- do.call(call, list(df[[i]]))
}
str(df)
# 'data.frame': 5 obs. of 4 variables:
# $ V1: int 1 2 3 4 5
# $ V2: num 6 7 8 9 10
# $ V3: chr "11" "12" "13" "14" ...
# $ V4: Factor w/ 5 levels "16","17","18",..: 1 2 3 4 5
Upvotes: 1
Reputation: 39154
We can use mapply
and provide the functions as a list to convert the columns.
df <- as.data.frame(matrix(1:20, 5, 4))
df[] <- mapply(function(x, FUN) FUN(x),
df,
list(as.integer, as.numeric, as.character, as.factor),
SIMPLIFY = FALSE)
str(df)
# 'data.frame': 5 obs. of 4 variables:
# $ V1: int 1 2 3 4 5
# $ V2: num 6 7 8 9 10
# $ V3: chr "11" "12" "13" "14" ...
# $ V4: Factor w/ 5 levels "16","17","18",..: 1 2 3 4 5
Upvotes: 7