Respostas:
Como (ainda) ninguém recebeu a marca de seleção, suponho que você tenha algum problema prático em mente, principalmente porque você não especificou em que tipo de vetor deseja converter numeric. Sugiro que você aplique a transformfunção para concluir sua tarefa.
Agora estou prestes a demonstrar certa "anomalia de conversão":
# create dummy data.frame
d <- data.frame(char = letters[1:5],
fake_char = as.character(1:5),
fac = factor(1:5),
char_fac = factor(letters[1:5]),
num = 1:5, stringsAsFactors = FALSE)
Vamos dar uma olhada em data.frame
> d
char fake_char fac char_fac num
1 a 1 1 a 1
2 b 2 2 b 2
3 c 3 3 c 3
4 d 4 4 d 4
5 e 5 5 e 5
e vamos correr:
> sapply(d, mode)
char fake_char fac char_fac num
"character" "character" "numeric" "numeric" "numeric"
> sapply(d, class)
char fake_char fac char_fac num
"character" "character" "factor" "factor" "integer"
Agora você provavelmente se pergunta "Onde está uma anomalia?" Bem, eu me deparei com coisas bastante peculiares em R, e isso não é a coisa mais confusa, mas pode confundir você, especialmente se você ler isso antes de rolar na cama.
Aqui vai: as duas primeiras colunas são character. Eu deliberadamente chamado 2 nd um fake_char. Descubra a semelhança dessa charactervariável com uma que Dirk criou em sua resposta. Na verdade, é um numericalvetor convertido em character. 3 rd e 4 th coluna são factor, e o último é "puramente" numeric.
Se você utilizar a transformfunção, poderá converter a variável fake_charem numeric, mas não a charprópria variável.
> transform(d, char = as.numeric(char))
char fake_char fac char_fac num
1 NA 1 1 a 1
2 NA 2 2 b 2
3 NA 3 3 c 3
4 NA 4 4 d 4
5 NA 5 5 e 5
Warning message:
In eval(expr, envir, enclos) : NAs introduced by coercion
mas se você fizer o mesmo fake_chare char_factiver sorte, sairá sem NA:
> transform(d, fake_char = as.numeric(fake_char),
char_fac = as.numeric(char_fac))
char fake_char fac char_fac num
1 a 1 1 1 1
2 b 2 2 2 2
3 c 3 3 3 3
4 d 4 4 4 4
5 e 5 5 5 5
Se você salvar transformado data.framee verificar modee class, obterá:
> D <- transform(d, fake_char = as.numeric(fake_char),
char_fac = as.numeric(char_fac))
> sapply(D, mode)
char fake_char fac char_fac num
"character" "numeric" "numeric" "numeric" "numeric"
> sapply(D, class)
char fake_char fac char_fac num
"character" "numeric" "factor" "numeric" "integer"
Portanto, a conclusão é: Sim, você pode converter um charactervetor em numericum, mas apenas se os elementos forem "conversíveis" em numeric. Se houver apenas um characterelemento no vetor, você receberá um erro ao tentar converter esse vetor em numericalum.
E apenas para provar meu argumento:
> err <- c(1, "b", 3, 4, "e")
> mode(err)
[1] "character"
> class(err)
[1] "character"
> char <- as.numeric(err)
Warning message:
NAs introduced by coercion
> char
[1] 1 NA 3 4 NA
E agora, apenas por diversão (ou prática), tente adivinhar a saída desses comandos:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Atenciosamente Patrick Burns! =)
Algo que me ajudou: se você tiver intervalos de variáveis para converter (ou apenas mais de um), poderá usar sapply.
Um pouco absurdo, mas apenas por exemplo:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Digamos que as colunas 3, 6 a 15 e 37 de seu dataframe precisem ser convertidas para numéricas.
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapplychamada no as.data.frame()lado direito, como sugerido por @Mehrad Mahmoudian abaixo, ela funcionará.
se xé o nome da coluna do quadro de dados date xé do tipo fator, use:
as.numeric(as.character(dat$x))
as.characterfato é o que eu estava procurando. Caso contrário, a conversão às vezes dá errado. Ao menos em meu caso.
Error: (list) object cannot be coerced to type 'double'embora eu estivesse razoavelmente certo de que meu vetor não tinha caracteres / pontuações. Então eu tentei as.numeric(as.character(dat$x))e funcionou. Agora não tenho certeza se minha coluna é de fato apenas números inteiros ou não!
Embora sua pergunta seja estritamente numérica, há muitas conversões difíceis de entender ao iniciar o R. Vou tentar abordar métodos para ajudar. Esta pergunta é semelhante a esta pergunta .
A conversão de tipo pode ser um problema em R porque (1) os fatores não podem ser convertidos diretamente para numéricos, eles precisam ser convertidos para a classe de caracteres primeiro, (2) as datas são um caso especial com o qual você normalmente precisa lidar separadamente e (3) fazer um loop pelas colunas do quadro de dados pode ser complicado. Felizmente, o "arrumado" resolveu a maioria dos problemas.
Esta solução usa mutate_each()para aplicar uma função a todas as colunas em um quadro de dados. Nesse caso, queremos aplicar a type.convert()função, que converte seqüências de caracteres em numérico, sempre que possível. Como R ama fatores (não sei por que) as colunas de caracteres que devem permanecer são alteradas para fator. Para corrigir isso, a mutate_if()função é usada para detectar colunas que são fatores e mudar para caractere. Por fim, eu queria mostrar como o lubridato pode ser usado para alterar um carimbo de data / hora na classe de caracteres para data e hora, porque esse também é um obstáculo para iniciantes.
library(tidyverse)
library(lubridate)
# Recreate data that needs converted to numeric, date-time, etc
data_df
#> # A tibble: 5 × 9
#> TIMESTAMP SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
#> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
#> 1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
#> 2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
#> 3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
#> 4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
#> 5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
# Converting columns to numeric using "tidyverse"
data_df %>%
mutate_all(type.convert) %>%
mutate_if(is.factor, as.character) %>%
mutate(TIMESTAMP = as_datetime(TIMESTAMP, tz = Sys.timezone()))
#> # A tibble: 5 × 9
#> TIMESTAMP SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
#> <dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
#> 1 2012-05-04 09:30:00 BAC T 7.890 38538 F 7.89 523 7.90
#> 2 2012-05-04 09:30:01 BAC Z 7.885 288 @ 7.88 61033 7.90
#> 3 2012-05-04 09:30:03 BAC X 7.890 1000 @ 7.88 1974 7.89
#> 4 2012-05-04 09:30:07 BAC T 7.890 19052 F 7.88 1058 7.89
#> 5 2012-05-04 09:30:08 BAC Y 7.890 85053 F 7.88 108101 7.90
mutate_all(type.convert, as.is=TRUE)vez de mutate_all(type.convert), poderá remover / evitar mutate_if(is.factor, as.character)encurtar o comando. as.isé um argumento type.convert()que indica se deve converter cadeias de caracteres como caracteres ou como fatores. Por padrão, as.is=FALSEem type.convert()(ou seja, converte seqüências de caracteres em classe de fator em vez de classe de caractere).
Tim está correto e Shane tem uma omissão. Aqui estão alguns exemplos adicionais:
R> df <- data.frame(a = as.character(10:15))
R> df <- data.frame(df, num = as.numeric(df$a),
numchr = as.numeric(as.character(df$a)))
R> df
a num numchr
1 10 1 10
2 11 2 11
3 12 3 12
4 13 4 13
5 14 5 14
6 15 6 15
R> summary(df)
a num numchr
10:1 Min. :1.00 Min. :10.0
11:1 1st Qu.:2.25 1st Qu.:11.2
12:1 Median :3.50 Median :12.5
13:1 Mean :3.50 Mean :12.5
14:1 3rd Qu.:4.75 3rd Qu.:13.8
15:1 Max. :6.00 Max. :15.0
R>
Nosso data.frameagora tem um resumo da coluna fator (contagens) e resumos numéricos do as.numeric()--- que é errado , uma vez que tem os níveis de fator numéricos --- e o resumo (correta) da as.numeric(as.character()).
Com o código a seguir, você pode converter todas as colunas do quadro de dados em numérico (X é o quadro de dados que queremos converter nas colunas):
as.data.frame(lapply(X, as.numeric))
e para converter a matriz inteira em numérica, você tem duas maneiras:
mode(X) <- "numeric"
ou:
X <- apply(X, 2, as.numeric)
Como alternativa, você pode usar a data.matrixfunção para converter tudo em numérico, embora esteja ciente de que os fatores podem não ser convertidos corretamente, portanto, é mais seguro converter tudo em characterprimeiro:
X <- sapply(X, as.character)
X <- data.matrix(X)
Eu costumo usar este último se quiser converter para matriz e numérico simultaneamente
Se você tiver problemas com:
as.numeric(as.character(dat$x))
Dê uma olhada nas suas marcas decimais. Se eles são "," em vez de "." (por exemplo, "5,3") o acima não funcionará.
Uma solução potencial é:
as.numeric(gsub(",", ".", dat$x))
Eu acredito que isso é bastante comum em alguns países que não falam inglês.
Maneira universal usando type.convert()e rapply():
convert_types <- function(x) {
stopifnot(is.list(x))
x[] <- rapply(x, utils::type.convert, classes = "character",
how = "replace", as.is = TRUE)
return(x)
}
d <- data.frame(char = letters[1:5],
fake_char = as.character(1:5),
fac = factor(1:5),
char_fac = factor(letters[1:5]),
num = 1:5, stringsAsFactors = FALSE)
sapply(d, class)
#> char fake_char fac char_fac num
#> "character" "character" "factor" "factor" "integer"
sapply(convert_types(d), class)
#> char fake_char fac char_fac num
#> "character" "integer" "factor" "factor" "integer"
as.is = TRUEse você deseja converter o seu personagem para numérico ou fatores
matrixde mudanças numéricos classes=matrixerrados fora primeiro argumento deve ser de caráter modo
Para converter uma coluna de quadro de dados em numérico, basta fazer o seguinte: -
fator para numérico: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Embora outros tenham abordado o tópico muito bem, eu gostaria de adicionar esse pensamento / sugestão rápida adicional. Você pode usar o regexp para verificar antecipadamente se os caracteres potencialmente consistem apenas em números.
for(i in seq_along(names(df)){
potential_numcol[i] <- all(!grepl("[a-zA-Z]",d[,i]))
}
# and now just convert only the numeric ones
d <- sapply(d[,potential_numcol],as.numeric)
Para expressões regulares mais sofisticadas e um porquê de aprender / experimentar seu poder, consulte este site realmente agradável: http://regexr.com/
Considerando que podem existir colunas char, isso se baseia em @Abdou na resposta Obter tipos de colunas da planilha do Excel automaticamente :
makenumcols<-function(df){
df<-as.data.frame(df)
df[] <- lapply(df, as.character)
cond <- apply(df, 2, function(x) {
x <- x[!is.na(x)]
all(suppressWarnings(!is.na(as.numeric(x))))
})
numeric_cols <- names(df)[cond]
df[,numeric_cols] <- sapply(df[,numeric_cols], as.numeric)
return(df)
}
df<-makenumcols(df)
Se o quadro de dados tiver vários tipos de colunas, alguns caracteres e alguns numéricos, tente o seguinte para converter apenas as colunas que contêm valores numéricos em numérico:
for (i in 1:length(data[1,])){
if(length(as.numeric(data[,i][!is.na(data[,i])])[!is.na(as.numeric(data[,i][!is.na(data[,i])]))])==0){}
else {
data[,i]<-as.numeric(data[,i])
}
}
com hablar :: convert
Para converter facilmente várias colunas em diferentes tipos de dados, você pode usar hablar::convert. Sintaxe simples: df %>% convert(num(a))converte a coluna a de df em numérico.
Exemplo detalhado
Permite converter todas as colunas de mtcarspara caractere.
df <- mtcars %>% mutate_all(as.character) %>% as_tibble()
> df
# A tibble: 32 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 21 6 160 110 3.9 2.62 16.46 0 1 4 4
2 21 6 160 110 3.9 2.875 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
Com hablar::convert:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
resulta em:
# A tibble: 32 x 11
mpg cyl disp hp drat wt qsec vs am gear carb
<chr> <int> <dbl> <dbl> <dbl> <dbl> <chr> <int> <chr> <fct> <chr>
1 21 6 160 110 3.9 2.62 16.46 0 1 4 4
2 21 6 160 110 3.9 2.88 17.02 0 1 4 4
3 22.8 4 108 93 3.85 2.32 18.61 1 1 4 1
4 21.4 6 258 110 3.08 3.22 19.44 1 0 3 1
Para converter caractere em numérico, você deve convertê-lo em fator aplicando
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Você precisa criar duas colunas com os mesmos dados, porque uma coluna não pode ser convertida em numérica. Se você fizer uma conversão, ocorrerá o erro abaixo
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
então, depois de fazer duas colunas dos mesmos dados, aplique
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
ele transformará o caractere em numérico com êxito
dfé o seu quadro de dados. xé uma coluna que dfvocê deseja converter
as.numeric(factor(df$x))
Se você não se preocupa em preservar os fatores e deseja aplicá-lo a qualquer coluna que possa ser convertida para numérica, usei o script abaixo. se df é o seu dataframe original, você pode usar o script abaixo.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))