Risposte:
Dato che (ancora) nessuno ha ottenuto il segno di spunta, presumo che tu abbia qualche problema pratico in mente, soprattutto perché non hai specificato in quale tipo di vettore vuoi convertire numeric
. Ti suggerisco di applicare la transform
funzione per completare il tuo compito.
Ora sto per dimostrare una certa "anomalia di conversione":
# 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)
Diamo un'occhiata 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 corriamo:
> 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"
Ora probabilmente ti chiedi "Dov'è un'anomalia?" Bene, mi sono imbattuto in cose abbastanza peculiari in R, e questa non è la cosa più confusa, ma può confonderti, specialmente se leggi questo prima di rotolare nel letto.
Ecco qui: le prime due colonne sono character
. Ho volutamente chiamato 2 ° uno fake_char
. Trova la somiglianza di questa character
variabile con quella creata da Dirk nella sua risposta. In realtà è un numerical
vettore convertito in character
. La terza e la quarta colonna sono factor
, e l'ultima è "puramente" numeric
.
Se si utilizza la transform
funzione, è possibile convertire fake_char
in numeric
, ma non nella char
variabile stessa.
> 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
ma se fai la stessa cosa su fake_char
e char_fac
, sarai fortunato e scapperai senza 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 salvi trasformato data.frame
e controlli per mode
e class
, otterrai:
> 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"
Quindi, la conclusione è: Sì, puoi convertire il character
vettore in numeric
uno, ma solo se i suoi elementi sono "convertibili" in numeric
. Se c'è solo un character
elemento nel vettore, otterrai un errore quando provi a convertire quel vettore in numerical
uno.
E solo per dimostrare il mio punto:
> 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 ora, solo per divertimento (o pratica), prova a indovinare l'output di questi comandi:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Cordiali saluti a Patrick Burns! =)
Qualcosa che mi ha aiutato: se hai gamme di variabili da convertire (o solo più di una), puoi usare sapply
.
Un po 'senza senso ma solo per esempio:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Supponiamo che le colonne 3, 6-15 e 37 di te, il frame di dati debba essere convertito in uno numerico, possano:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapply
chiamata as.data.frame()
sul lato destro, come suggerito da @Mehrad Mahmoudian di seguito, funzionerà.
se x
è il nome della colonna del frame di dati dat
ed x
è di tipo fattore, utilizzare:
as.numeric(as.character(dat$x))
as.character
è davvero quello che stavo cercando. Altrimenti la conversione a volte va storto. Almeno nel mio caso.
Error: (list) object cannot be coerced to type 'double'
anche se ero ragionevolmente sicuro che il mio vettore non avesse caratteri / punteggiatura. Poi ho provato as.numeric(as.character(dat$x))
e ha funzionato. Ora non sono sicuro che la mia colonna sia in realtà solo numeri interi o no!
Mentre la tua domanda è strettamente numerica, ci sono molte conversioni che sono difficili da capire quando inizi R. Cercherò di indirizzare i metodi per aiutare. Questa domanda è simile a questa domanda .
La conversione del tipo può essere una seccatura in R perché (1) i fattori non possono essere convertiti direttamente in valori numerici, devono prima essere convertiti in classe di caratteri, (2) le date sono un caso speciale che in genere è necessario affrontare separatamente e (3) eseguire il ciclo tra le colonne del frame di dati può essere complicato. Fortunatamente, il "tidyverse" ha risolto la maggior parte dei problemi.
Questa soluzione utilizza mutate_each()
per applicare una funzione a tutte le colonne in un frame di dati. In questo caso, vogliamo applicare la type.convert()
funzione, che converte le stringhe in valori numerici laddove possibile. Perché R ama i fattori (non so perché) le colonne di caratteri che dovrebbero rimanere personaggi vengono cambiate in fattore. Per risolvere questo problema, la mutate_if()
funzione viene utilizzata per rilevare colonne che sono fattori e cambiano carattere. Infine, volevo mostrare come lubridate può essere usato per cambiare un timestamp nella classe di caratteri in data-ora perché questo è spesso anche un blocco per principianti.
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)
invece di mutate_all(type.convert)
, è possibile rimuovere / evitare mutate_if(is.factor, as.character)
di abbreviare il comando. as.is
è un argomento type.convert()
che indica se deve convertire le stringhe come caratteri o come fattori. Per impostazione predefinita, as.is=FALSE
in type.convert()
(ovvero, converte le stringhe in classe di fattori anziché in classe di caratteri).
Tim ha ragione e Shane ha un'omissione. Ecco altri esempi:
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>
Il nostro data.frame
ora ha un riepilogo della colonna del fattore (conteggi) e dei riassunti numerici del as.numeric()
--- che è sbagliato in quanto ha ottenuto i livelli del fattore numerico --- e il riassunto (corretto) del as.numeric(as.character())
.
Con il seguente codice è possibile convertire tutte le colonne del frame di dati in numeriche (X è il frame di dati che vogliamo convertire sono le colonne):
as.data.frame(lapply(X, as.numeric))
e per convertire l'intera matrice in valori numerici hai due modi:
mode(X) <- "numeric"
o:
X <- apply(X, 2, as.numeric)
In alternativa puoi usare la data.matrix
funzione per convertire tutto in valori numerici, sebbene tieni presente che i fattori potrebbero non essere convertiti correttamente, quindi è più sicuro convertire tutto in character
primo:
X <- sapply(X, as.character)
X <- data.matrix(X)
Di solito uso quest'ultimo se voglio convertire simultaneamente in matrice e numerico
Se riscontri problemi con:
as.numeric(as.character(dat$x))
Dai un'occhiata ai segni decimali. Se sono "," anziché "." (es. "5,3") quanto sopra non funzionerà.
Una potenziale soluzione è:
as.numeric(gsub(",", ".", dat$x))
Credo che questo sia abbastanza comune in alcuni paesi non di lingua inglese.
Modo universale 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 = TRUE
se vuoi convertire il tuo personaggio in numerico o in fattori
matrix
di modifiche numeriche classes=matrix
errate, il primo argomento deve essere di tipo mode
Per convertire una colonna di frame di dati in valori numerici devi solo fare: -
fattore numerico: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Sebbene altri abbiano trattato abbastanza bene l'argomento, vorrei aggiungere questo breve suggerimento / suggerimento aggiuntivo. È possibile utilizzare regexp per verificare in anticipo se i caratteri sono potenzialmente costituiti solo da numeri.
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)
Per espressioni regolari più sofisticate e un chiaro motivo per imparare / sperimentare il loro potere, visita questo sito Web davvero carino: http://regexr.com/
Considerando che potrebbero esistere colonne di caratteri, questo si basa su @Abdou in Ottieni tipi di colonne di foglio Excel che rispondono 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 il frame di dati ha più tipi di colonne, alcuni caratteri, alcuni numerici provano quanto segue per convertire solo le colonne che contengono valori numerici in numerici:
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])
}
}
con hablar :: convert
Per convertire facilmente più colonne in diversi tipi di dati è possibile utilizzare hablar::convert
. Sintassi semplice:df %>% convert(num(a))
converte la colonna a da df in numerico.
Esempio dettagliato
Consente di convertire tutte le colonne mtcars
in carattere.
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
Con hablar::convert
:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
risulta in:
# 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
Per convertire il carattere in numerico devi convertirlo in fattore applicandolo
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Devi creare due colonne con gli stessi dati, perché una colonna non può essere convertita in numerico. Se si esegue una conversione, viene visualizzato l'errore seguente
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
quindi, dopo aver fatto due colonne degli stessi dati si applicano
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
trasformerà il carattere in numerico correttamente
df
è il tuo dataframe. x
è una colonna df
che vuoi convertire
as.numeric(factor(df$x))
Se non ti interessa conservare i fattori e vuoi applicarlo a qualsiasi colonna che può essere convertita in numerico, ho usato lo script qui sotto. se df è il tuo frame di dati originale, puoi utilizzare lo script seguente.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))
Ho fatto riferimento alla soluzione di Shane e Joran tra l'altro