Réponses:
Puisque (encore) personne n'a de coche, je suppose que vous avez un problème pratique à l'esprit, principalement parce que vous n'avez pas spécifié le type de vecteur que vous souhaitez convertir numeric. Je suggère que vous appliquiez la transformfonction afin de terminer votre tâche.
Maintenant, je suis sur le point de démontrer certaines "anomalies de conversion":
# 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)
Jetons un coup d'œil à 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
et laissez-nous courir:
> 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"
Maintenant, vous vous demandez probablement "Où est une anomalie?" Eh bien, je suis tombé sur des choses assez particulières dans R, et ce n'est pas la chose la plus déroutante, mais cela peut vous dérouter, surtout si vous lisez ceci avant de vous coucher.
Voilà: les deux premières colonnes sont character. J'ai délibérément appelé 2 e un fake_char. Repérez la similitude de cette charactervariable avec celle créée par Dirk dans sa réponse. C'est en fait un numericalvecteur converti en character. 3 ème et 4 ème colonne sont factor, et le dernier est « purement » numeric.
Si vous utilisez la transformfonction, vous pouvez convertir la fake_charen numeric, mais pas la charvariable elle-même.
> 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
mais si vous faites la même chose fake_charet que char_facvous aurez de la chance et que vous vous en sortirez sans 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
Si vous enregistrez transformé data.frameet vérifiez modeet class, vous obtiendrez:
> 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"
Donc, la conclusion est: oui, vous pouvez convertir un charactervecteur en un numeric, mais seulement si ses éléments sont "convertibles" en numeric. S'il n'y a qu'un seul characterélément dans le vecteur, vous obtiendrez une erreur lorsque vous tenterez de convertir ce vecteur en numericalun.
Et juste pour prouver mon point:
> 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
Et maintenant, juste pour le plaisir (ou la pratique), essayez de deviner la sortie de ces commandes:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Cordialement à Patrick Burns! =)
Quelque chose qui m'a aidé: si vous avez des plages de variables à convertir (ou juste plus d'un), vous pouvez utiliser sapply.
Un peu absurde mais juste par exemple:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Supposons que les colonnes 3, 6-15 et 37 de votre trame de données doivent être converties en numérique, on pourrait:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
sapplyappel as.data.frame()sur le côté droit, comme @Mehrad Mahmoudian l'a suggéré ci-dessous, cela fonctionnera.
si xest le nom de colonne de la trame de données datet xest de type facteur, utilisez:
as.numeric(as.character(dat$x))
as.charactereffet, c'est ce que je cherchais. Sinon, la conversion se passe parfois mal. Du moins dans mon cas.
Error: (list) object cannot be coerced to type 'double'même si j'étais raisonnablement sûr que mon vecteur n'avait pas de caractères / signes de ponctuation. Ensuite, j'ai essayé as.numeric(as.character(dat$x))et cela a fonctionné. Maintenant, je ne sais pas si ma colonne est en fait uniquement des entiers ou non!
Bien que votre question soit strictement numérique, il existe de nombreuses conversions difficiles à comprendre au début de R. Je vais essayer de trouver des méthodes pour vous aider. Cette question est similaire à cette question .
La conversion de type peut être pénible dans R car (1) les facteurs ne peuvent pas être convertis directement en numérique, ils doivent d'abord être convertis en classe de caractères, (2) les dates sont un cas spécial que vous devez généralement traiter séparément, et (3) le bouclage entre les colonnes de trame de données peut être délicat. Heureusement, le "tidyverse" a résolu la plupart des problèmes.
Cette solution utilise mutate_each()pour appliquer une fonction à toutes les colonnes d'un bloc de données. Dans ce cas, nous voulons appliquer la type.convert()fonction, qui convertit les chaînes en numérique où cela est possible. Parce que R aime les facteurs (je ne sais pas pourquoi) les colonnes de caractères qui devraient rester en caractère sont transformées en facteur. Pour résoudre ce problème, la mutate_if()fonction est utilisée pour détecter les colonnes qui sont des facteurs et passer au caractère. Enfin, je voulais montrer comment lubridate peut être utilisé pour changer un horodatage dans une classe de caractères en date-heure car c'est aussi souvent un blocage pour les débutants.
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)au lieu de mutate_all(type.convert), vous pouvez supprimer / éviter mutate_if(is.factor, as.character)pour raccourcir la commande. as.isest un argument type.convert()qui indique s'il doit convertir des chaînes en caractères ou en facteurs. Par défaut, as.is=FALSEdans type.convert()(c'est- à -dire, convertit les chaînes en classe de facteurs au lieu de classe de caractères).
Tim a raison et Shane a une omission. Voici des exemples supplémentaires:
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>
Notre a data.framemaintenant un résumé de la colonne des facteurs (nombre) et des résumés numériques du as.numeric()--- ce qui est faux car il a obtenu les niveaux des facteurs numériques --- et le résumé (correct) du as.numeric(as.character()).
Avec le code suivant, vous pouvez convertir toutes les colonnes du bloc de données en numérique (X est le bloc de données que nous voulons convertir ses colonnes):
as.data.frame(lapply(X, as.numeric))
et pour convertir la matrice entière en numérique, vous avez deux façons: Soit:
mode(X) <- "numeric"
ou:
X <- apply(X, 2, as.numeric)
Alternativement, vous pouvez utiliser la data.matrixfonction pour tout convertir en numérique, mais sachez que les facteurs peuvent ne pas être convertis correctement, il est donc plus sûr de tout convertir en characterpremier:
X <- sapply(X, as.character)
X <- data.matrix(X)
J'utilise habituellement ce dernier si je veux convertir simultanément en matrice et numérique
Si vous rencontrez des problèmes avec:
as.numeric(as.character(dat$x))
Jetez un œil à vos décimales. S'ils sont "," au lieu de "." (par exemple "5,3") ce qui précède ne fonctionnera pas.
Une solution potentielle est:
as.numeric(gsub(",", ".", dat$x))
Je pense que c'est assez courant dans certains pays non anglophones.
Manière universelle en utilisant type.convert()et 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 = TRUEsi vous souhaitez convertir votre personnage en chiffres ou en facteurs
matrixà des modifications numériques classes=matrixerroné le premier argument doit être de caractère mode
Pour convertir une colonne de bloc de données en numérique, il vous suffit de faire: -
facteur en numérique: -
data_frame$column <- as.numeric(as.character(data_frame$column))
sapply(data_frame,function(x) as.numeric(as.character(x)))
Bien que d'autres aient assez bien couvert le sujet, je voudrais ajouter cette pensée / astuce rapide supplémentaire. Vous pouvez utiliser regexp pour vérifier à l'avance si les caractères ne sont potentiellement composés que de chiffres.
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)
Pour des expressions régulières plus sophistiquées et une bonne raison d'apprendre / expérimenter leur puissance, consultez ce site Web vraiment sympa: http://regexr.com/
Étant donné qu'il peut exister des colonnes de caractères, celles-ci sont basées sur @Abdou dans Obtenir les types de colonnes de la feuille Excel, répondre automatiquement :
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)
Si la trame de données a plusieurs types de colonnes, certains caractères, certains numériques, essayez ce qui suit pour convertir uniquement les colonnes qui contiennent des valeurs numériques en numériques:
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])
}
}
avec hablar :: convert
Pour convertir facilement plusieurs colonnes en différents types de données, vous pouvez utiliser hablar::convert. Syntaxe simple: df %>% convert(num(a))convertit la colonne a de df en numérique.
Exemple détaillé
Permet de convertir toutes les colonnes de mtcarsen caractère.
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
Avec hablar::convert:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
résulte en:
# 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
Pour convertir un caractère en numérique, vous devez le convertir en facteur en appliquant
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Vous devez créer deux colonnes avec les mêmes données, car une colonne ne peut pas être convertie en numérique. Si vous effectuez une conversion, cela donne l'erreur ci-dessous
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
donc, après avoir fait deux colonnes des mêmes données s'appliquent
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
il transformera le caractère numérique avec succès
dfist votre trame de données. xest une colonne que dfvous souhaitez convertir
as.numeric(factor(df$x))
Si vous ne vous souciez pas de préserver les facteurs et que vous souhaitez l'appliquer à n'importe quelle colonne pouvant être convertie en numérique, j'ai utilisé le script ci-dessous. si df est votre trame de données d'origine, vous pouvez utiliser le script ci-dessous.
df[] <- lapply(df, as.character)
df <- data.frame(lapply(df, function(x) ifelse(!is.na(as.numeric(x)), as.numeric(x), x)))