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 transform
fonction 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 character
variable avec celle créée par Dirk dans sa réponse. C'est en fait un numerical
vecteur converti en character
. 3 ème et 4 ème colonne sont factor
, et le dernier est « purement » numeric
.
Si vous utilisez la transform
fonction, vous pouvez convertir la fake_char
en numeric
, mais pas la char
variable 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_char
et que char_fac
vous 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.frame
et vérifiez mode
et 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 character
vecteur 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 numerical
un.
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)
sapply
appel as.data.frame()
sur le côté droit, comme @Mehrad Mahmoudian l'a suggéré ci-dessous, cela fonctionnera.
si x
est le nom de colonne de la trame de données dat
et x
est de type facteur, utilisez:
as.numeric(as.character(dat$x))
as.character
effet, 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.is
est un argument type.convert()
qui indique s'il doit convertir des chaînes en caractères ou en facteurs. Par défaut, as.is=FALSE
dans 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.frame
maintenant 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.matrix
fonction 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 character
premier:
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 = TRUE
si vous souhaitez convertir votre personnage en chiffres ou en facteurs
matrix
à des modifications numériques classes=matrix
erroné 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 mtcars
en 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
df
ist votre trame de données. x
est une colonne que df
vous 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)))