TransWikia.com

Como faço para retornar para "double" do df original?

Stack Overflow em Português Asked by Thaissa on October 7, 2020

Quando converto o df de "factor" para "numeric" os valores se tornam inteiros. Como faço para retornar para "double" do df original?

df <- read.csv2(file.choose())

View(df)
str(df)  

df1 <- as.numeric(df[1:12])  
df1 <- as.numeric(unlist(df))
df1 <- lapply(df, as.numeric)    

Também já tentei dessa forma e não consegui

df3 <- as.double(df[1:12]) 
df3 <- as.double(unlist(df))
df3 <- lapply(df,as.double)

str(df1)

df2 <- as.data.frame(df1)
View(df2)  

Resumindo:

head(df)
  fixed.acidity volatile.acidity citric.acid residual.sugar chlorides
1           7.4              0.7           0            1.9     0.076
2           7.8             0.88           0            2.6     0.098
3           7.8             0.76        0.04            2.3     0.092
4          11.2             0.28        0.56            1.9     0.075
5           7.4              0.7           0            1.9     0.076
6           7.4             0.66           0            1.8     0.075


head(df2)
  fixed.acidity volatile.acidity citric.acid residual.sugar chlorides
1            71               77           1             11        40
2            75              113           1             31        62
3            75               89           5             26        56
4            13               13          57             11        39
5            71               77           1             11        40
6            71               69           1             10        39

2 Answers

Em primeiro lugar ver quais as colunas que são de classe "factor". Serão estas as colunas a transformar.

str(df)
#'data.frame':  6 obs. of  5 variables:
# $ fixed.acidity   : Factor w/ 3 levels "7.4","7.8","11.2": 1 2 2 3 1 1
# $ volatile.acidity: Factor w/ 5 levels "0.28","0.66",..: 3 5 4 1 3 2
# $ citric.acid     : Factor w/ 3 levels "0","0.04","0.56": 1 1 2 3 1 1
# $ residual.sugar  : Factor w/ 4 levels "1.8","1.9","2.3",..: 2 4 3 2 2 1
# $ chlorides       : Factor w/ 4 levels "0.075","0.076",..: 2 4 3 1 2 1

Isto pode ser obtido programaticamente com

ind_cols <- sapply(df, is.factor)
ind_cols
#   fixed.acidity volatile.acidity      citric.acid   residual.sugar        chlorides 
#            TRUE             TRUE             TRUE             TRUE             TRUE 

Este índice lógico pode ser usado diretamente no que se segue, mas tendo em conta que na pergunta as colunas em causa estão definidas por um vetor númerico dado, 1:12, também vou usar um vetor previamente definido, com menos colunas, as dos dados exemplo.

Para transformar as colunas, é necessário ter o índice de colunas tanto no data.frame resultado como no data.frame ao qual vai ser aplicada a função anónima.

ind_cols <- 1:5
df[ind_cols] <- lapply(df[ind_cols], function(x) as.numeric(as.character(x)))

Verificar o resultado.

str(df)
#'data.frame':  6 obs. of  5 variables:
# $ fixed.acidity   : num  7.4 7.8 7.8 11.2 7.4 7.4
# $ volatile.acidity: num  0.7 0.88 0.76 0.28 0.7 0.66
# $ citric.acid     : num  0 0 0.04 0.56 0 0
# $ residual.sugar  : num  1.9 2.6 2.3 1.9 1.9 1.8
# $ chlorides       : num  0.076 0.098 0.092 0.075 0.076 0.075
 
head(df)
#  fixed.acidity volatile.acidity citric.acid residual.sugar chlorides
#1           7.4             0.70        0.00            1.9     0.076
#2           7.8             0.88        0.00            2.6     0.098
#3           7.8             0.76        0.04            2.3     0.092
#4          11.2             0.28        0.56            1.9     0.075
#5           7.4             0.70        0.00            1.9     0.076
#6           7.4             0.66        0.00            1.8     0.075

Nota

O problema está resolvido acima, mas este problema é tão frequente que talvez seja desejável ter uma função que transforme um objeto de classe "factor" em um objeto de classe "numeric" ou typeof "double", o que é idêntico. Para isso, pode-se tirar partido do sistema de classes S3 e escrever um método para as.numeric ou as.double.

Da documentação, help("as.numeric"):

as.numeric is a generic function, but S3 methods must be written for as.double. It is identical to as.double.

Tradução:

as.numeric é uma função genérica, mas os métodos S3 devem ser escritos para as.double. É idêntica a as.double.

Ou seja, o método vai ser escrito para as.double e tanto o nome de método S3 as.double como o nome as.numeric chamam o mesmo método.

as.double.factor <- function(x) as.double(as.character(x))

Agora o seguinte código obtém o resultado pretendido.

ind_cols <- 1:5
df[ind_cols] <- lapply(df[ind_cols], as.double)  # ou as.numeric

Dados

df <- read.table(text = "
  fixed.acidity volatile.acidity citric.acid residual.sugar chlorides
1           7.4              0.7           0            1.9     0.076
2           7.8             0.88           0            2.6     0.098
3           7.8             0.76        0.04            2.3     0.092
4          11.2             0.28        0.56            1.9     0.075
5           7.4              0.7           0            1.9     0.076
6           7.4             0.66           0            1.8     0.075
", header = TRUE)

df[] <- lapply(df, as.factor)

Answered by Rui Barradas on October 7, 2020

df <- data.frame(valores = as.factor(c(1.1, 2.0, 3.3, 1.1, 1.0, 2.0)))

df$valores_num <- as.double(as.character(df$valores))
df$valores_num

Pode tentar converter para 'string' primeiro e depois como double.

Saída:

1.1 2.0 3.3 1.1 1.0 2.0

Verificando o data.frame:

str(df)
 $ valores    : Factor w/ 4 levels "1","1.1","2",..: 2 3 4 2 1 3
 $ valores_num: num  1.1 2 3.3 1.1 1 2

Answered by lmonferrari on October 7, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP