Comment convertir une colonne de trame de données type numérique?
-
21-09-2019 - |
Question
Comment convertir une colonne de trame de données à un type numérique?
La solution
Depuis (encore) personne ne se coche, je suppose que vous avez une question pratique à l'esprit, la plupart du temps parce que vous n'avez pas spécifié quel type de vecteur que vous voulez convertir en numeric
. Je suggère que vous devez appliquer la fonction transform
afin de compléter votre tâche.
Maintenant, je suis sur le point de démontrer certaines "anomalie 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 courons:
> 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? » Je suis tombé sur des choses assez particulières dans R, et ce n'est pas le plus confondant chose, mais il peut vous confondre, surtout si vous lisez ceci avant de rouler dans le lit.
va ici: deux premières colonnes sont character
. J'ai délibérément appelé 2 e un fake_char
. Repérer la similitude de cette variable character
avec un Dirk créé dans sa réponse. Il est en fait un vecteur de numerical
converti en character
. 3 e et 4 e colonne sont factor
, et le dernier est "purement" numeric
.
Si vous utilisez la fonction transform
, vous pouvez convertir le fake_char
en numeric
, mais pas la variable char
lui-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 le faites même chose sur fake_char
et char_fac
, vous aurez de la chance, et vous en sortir sans NA de:
> 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 data.frame
transformé et vérifier 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"
Alors, la conclusion est: Oui, vous pouvez convertir vecteur character
en numeric
un, mais seulement si elle est des éléments sont "convertibles" à numeric
S'il est juste. un élément character
dans le vecteur, vous obtiendrez une erreur en essayant de convertir ce vecteur à 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 pratique), essayez de deviner la sortie de ces commandes:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Amitiés à Patrick Burns,! =)
Autres conseils
Quelque chose qui m'a aidé. Si vous avez des gammes de variables pour convertir (ou tout simplement plus d'un), vous pouvez utiliser sapply
Un peu de sens, mais juste par exemple:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Dites les colonnes 3, 6-15 et 37 vous dataframe doivent être converties en un numérique pourrait:
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
si x
est le nom de la colonne de dataframe dat
et x
est du facteur de type, utilisez:
as.numeric(as.character(dat$x))
J'ai ajouté un commentaire (note cant bas)
Juste pour ajouter user276042 et Pangratz
dat$x = as.numeric(as.character(dat$x))
Ceci remplacera les valeurs de x colonne existante
Tim est correct, et Shane a une omission. Voici d'autres exemples:
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 data.frame
a maintenant un résumé de la colonne de facteur (chiffres) et des résumés numériques du as.numeric()
--- qui est mauvais car il a obtenu les niveaux de facteur numérique --- et le (correct) résumé du as.numeric(as.character())
.
Avec le code suivant, vous pouvez convertir toutes les colonnes de trame de données à numérique (X est la trame de données que nous voulons convertir est des colonnes):
as.data.frame(lapply(X, as.numeric))
et pour convertir la matrice entière en numérique que vous avez deux façons: Soit:
mode(X) <- "numeric"
ou
X <- apply(X, 2, as.numeric)
Vous pouvez également utiliser la fonction data.matrix
pour tout convertir en numérique, bien être conscient que les facteurs risquent de ne pas se convertir correctement, il est donc plus sûr de convertir tout en character
premier:
X <- sapply(X, as.character)
X <- data.matrix(X)
Je l'habitude d'utiliser ce dernier si je veux pour convertir à la matrice et numérique simultanément
Bien que votre question est strictement numérique, il y a beaucoup de conversions qui sont difficiles à comprendre quand commencer R. Je vais viser les méthodes d'adresse pour vous aider. Cette question est similaire à href="https://stackoverflow.com/questions/42475874/how-can-i-convert-a-matrix-of-strings-into-a-tibble/42563612#42563612"> .
La conversion de type peut être une douleur dans R parce que (1) les facteurs ne peuvent pas être convertis directement en numérique, ils doivent être convertis en classe de premier caractère, (2) les dates sont un cas particulier que vous généralement besoin de traiter séparément, et (3) en boucle à travers 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 dans une trame de données. Dans ce cas, nous voulons appliquer la fonction type.convert()
, qui convertit les chaînes de numérique où il peut. Parce que R aime facteurs colonnes de caractères (ne sais pas pourquoi) qui devraient rester caractère sont changés au facteur. Pour résoudre ce problème, la fonction mutate_if()
est utilisé pour détecter les colonnes qui sont des facteurs et changer de caractère. Enfin, je voulais montrer comment lubridate peut être utilisé pour changer un horodatage en classe de caractères à ce jour en temps parce que c'est souvent un bloc d'achoppement 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
Si vous avez un problème avec:
as.numeric(as.character(dat$x))
Jetez un oeil à vos marques décimales. Si elles sont « » au lieu de « » (Par exemple "5,3") ci-dessus ne fonctionnera pas.
Une solution possible est la suivante:
as.numeric(gsub(",", ".", dat$x))
Je crois que c'est assez fréquent dans certains pays non anglophones.
façon universelle à l'aide 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"
Pour convertir une colonne de trame de données vous numérique suffit de faire: -
facteur numérique: -
data_frame$column <- as.numeric(as.character(data_frame$column))
Bien que d'autres ont couvert le sujet assez bien, je voudrais ajouter cette pensée / Hint rapide supplémentaire. Vous pouvez utiliser regexp pour vérifier à l'avance si les caractères sont composés potentiellement uniquement de valeurs numériques.
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 les expressions régulières plus sophistiquées et une nette pourquoi apprendre / expérience leur pouvoir voir ce site vraiment sympa: http: // RegExr. com /
Dans mon PC (R v.3.2.3), apply
ou sapply
donnent erreur. lapply
fonctionne bien.
dt[,2:4] <- lapply(dt[,2:4], function (x) as.factor(as.numeric(x)))
Si la trame de données a plusieurs types de colonnes, certains caractères, certains numérique essayez ce qui suit pour convertir seulement les colonnes qui contiennent des valeurs numériques numérique:
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])
}
}
hablar :: convertir
Pour convertir facilement plusieurs colonnes à différents types de données que vous pouvez utiliser hablar::convert
. syntaxe simple:. df %>% convert(num(a))
convertit une colonne de df numérique
Exemple détaillé
permet de convertir toutes les colonnes de caractère mtcars
.
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ésultats dans:
# 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
Considérant qu'il pourrait exister des colonnes char, ceci est basé sur @Abdou Get types de colonnes de feuille Excel automatiquement répondre à:
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)
Pour convertir le caractère à vous numérique devez convertir en facteur en appliquant
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Vous devez faire deux colonnes avec les mêmes données, car une colonne ne peut pas convertir en numérique. Si vous faites une conversion, il donne l'erreur ci-dessous
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
, après avoir fait deux colonnes des mêmes données appliquer
BankFinal1 <- transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
il transformera le caractère à succès numérique