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 transformfunzione 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 charactervariabile con quella creata da Dirk nella sua risposta. In realtà è un numericalvettore convertito in character. La terza e la quarta colonna sono factor, e l'ultima è "puramente" numeric.
Se si utilizza la transformfunzione, è possibile convertire fake_charin numeric, ma non nella charvariabile 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_chare 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.framee controlli per modee 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 charactervettore in numericuno, ma solo se i suoi elementi sono "convertibili" in numeric. Se c'è solo un characterelemento nel vettore, otterrai un errore quando provi a convertire quel vettore in numericaluno.
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)
sapplychiamata as.data.frame()sul lato destro, come suggerito da @Mehrad Mahmoudian di seguito, funzionerà.
se xè il nome della colonna del frame di dati dated 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=FALSEin 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.frameora 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.matrixfunzione per convertire tutto in valori numerici, sebbene tieni presente che i fattori potrebbero non essere convertiti correttamente, quindi è più sicuro convertire tutto in characterprimo:
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 = TRUEse vuoi convertire il tuo personaggio in numerico o in fattori
matrixdi modifiche numeriche classes=matrixerrate, 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 mtcarsin 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 dfche 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