Wie konvertiert man eine Datenrahmenspalte in einen numerischen Typ?
Da (noch) niemand ein Häkchen hat, gehe ich davon aus, dass Sie ein praktisches Problem haben, vor allem, weil Sie nicht angegeben haben, welchen Vektortyp Sie in numeric
konvertieren möchten. Ich schlage vor, dass Sie die transform
-Funktion anwenden sollten, um Ihre Aufgabe abzuschließen.
Jetzt zeige ich eine gewisse "Konvertierungsanomalie":
# 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)
Werfen wir einen Blick auf 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
und lass uns laufen:
> 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"
Jetzt fragst du dich wahrscheinlich "Wo ist eine Anomalie?" Nun, ich bin in R mit ziemlich seltsamen Dingen zusammengestoßen, und das ist es nicht das verwirrendste Sache, aber es kann Sie verwirren, vor allem, wenn Sie dies lesen, bevor Sie ins Bett rollen.
Hier ist: Die ersten beiden Spalten sind character
. Ich habe absichtlich 2 angerufennd ein fake_char
. Finden Sie die Ähnlichkeit dieser character
-Variable mit einer, die Dirk in seiner Antwort erstellt hat. Es ist tatsächlich ein numerical
-Vektor, der in character
konvertiert wird. 3rd und 4th Spalte sind factor
und die letzte ist "rein" numeric
.
Wenn Sie die transform
-Funktion verwenden, können Sie den fake_char
in numeric
konvertieren, nicht jedoch die char
-Variable.
> 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
aber wenn Sie dasselbe mit fake_char
und char_fac
tun, werden Sie Glück haben und ohne NAs davonkommen:
> 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
Wenn Sie transformierte data.frame
speichern und nach mode
und class
suchen, erhalten Sie Folgendes:
> 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"
Die Schlussfolgerung lautet also: Ja, Sie können den character
-Vektor in einen numeric
-Vektor konvertieren, jedoch nur, wenn seine Elemente in numeric
"konvertierbar" sind.</ i> Wenn es nur ein character
-Element im Vektor gibt, erhalten Sie eine Fehlermeldung, wenn Sie versuchen, diesen Vektor in ein numerical
-Element zu konvertieren.
Und nur um meinen Punkt zu beweisen:
> 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
Versuchen Sie jetzt, nur zum Spaß (oder zum Üben), die Ausgabe dieser Befehle zu erraten:
> fac <- as.factor(err)
> fac
???
> num <- as.numeric(fac)
> num
???
Herzliche Grüße an Patrick Burns! =)
Etwas, das mir geholfen hat: Wenn Sie über Variablenbereiche (oder nur über mehrere) verfügen, können Sie sapply
verwenden.
Etwas unsinnig, aber nur zum Beispiel:
data(cars)
cars[, 1:2] <- sapply(cars[, 1:2], as.factor)
Angenommen, die Spalten 3, 6-15 und 37 Ihres Datenrahmens müssen in numerische konvertiert werden.
dat[, c(3,6:15,37)] <- sapply(dat[, c(3,6:15,37)], as.numeric)
wenn x
der Spaltenname des Datenrahmens dat
ist und x
vom Typ Faktor ist, verwenden Sie
as.numeric(as.character(dat$x))
Ich hätte einen Kommentar hinzugefügt (keine schlechte Bewertung)
Einfach auf user276042 und pangratz hinzufügen
dat$x = as.numeric(as.character(dat$x))
Dadurch werden die Werte der vorhandenen Spalte x überschrieben
Tim ist richtig und Shane hat eine Unterlassung. Hier sind weitere Beispiele:
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>
Unser data.frame
enthält jetzt eine Zusammenfassung der Faktorspalte (Anzahl) und numerischen Zusammenfassungen der as.numeric()
--- welche false ist, da sie die numerischen Faktorstufen --- und die (korrekte) Zusammenfassung der as.numeric(as.character())
erhalten hat.
Mit dem folgenden Code können Sie alle Datenrahmenspalten in numerische konvertieren (X ist der Datenrahmen, dessen Spalten wir konvertieren möchten):
as.data.frame(lapply(X, as.numeric))
und für die Umwandlung der gesamten Matrix in eine numerische Form haben Sie zwei Möglichkeiten: Entweder:
mode(X) <- "numeric"
oder:
X <- apply(X, 2, as.numeric)
Alternativ können Sie die data.matrix
-Funktion verwenden, um alles in numerische Werte umzuwandeln. Beachten Sie jedoch, dass die Faktoren möglicherweise nicht korrekt konvertiert werden. Es ist daher sicherer, zuerst alles in character
zu konvertieren:
X <- sapply(X, as.character)
X <- data.matrix(X)
Normalerweise verwende ich das letzte wenn ich gleichzeitig in Matrix und Numerik konvertieren möchte
Während sich Ihre Frage streng auf numerische Fragen bezieht, gibt es viele Konvertierungen, die zu Beginn des Beginns von R schwer zu verstehen sind. Ich möchte Methoden ansprechen, die helfen. Diese Frage ist ähnlich zu Diese Frage .
Die Typkonvertierung kann in R ein Schmerz sein, da (1) Faktoren nicht direkt in numerische Werte konvertiert werden können, sondern zuerst in eine Zeichenklasse konvertiert werden müssen (3) Das Schleifen über Datenrahmenspalten kann schwierig sein. Glücklicherweise hat der "Tidyverse" die meisten Probleme gelöst.
Diese Lösung verwendet mutate_each()
, um eine Funktion auf alle Spalten in einem Datenrahmen anzuwenden. In diesem Fall möchten wir die Funktion type.convert()
anwenden, mit der Zeichenketten in numerische Zeichen umgewandelt werden, wo dies möglich ist. Weil R Faktoren liebt (nicht sicher, warum), werden Zeichenspalten, die Zeichen bleiben sollen, in Faktor geändert. Um dies zu beheben, wird die Funktion mutate_if()
verwendet, um Spalten zu erkennen, die Faktoren sind und in Zeichen geändert werden. Zuletzt wollte ich zeigen, wie man mit Lubridat einen Zeitstempel in der Zeichenklasse in Datum und Uhrzeit ändern kann, da dies auch für Anfänger häufig ein Blocking ist.
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
Wenn Sie Probleme haben mit:
as.numeric(as.character(dat$x))
Schauen Sie sich Ihre Dezimalstellen an. Wenn sie "," anstelle von "." (z. B. "5,3") das obige funktioniert nicht.
Eine mögliche Lösung ist:
as.numeric(gsub(",", ".", dat$x))
Ich glaube, dass dies in einigen nicht englischsprachigen Ländern durchaus üblich ist.
Universeller Weg mit type.convert()
und 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"
Um eine Datenrahmenspalte in eine Zahl umzuwandeln, müssen Sie nur Folgendes tun: -
faktor zu numerisch: -
data_frame$column <- as.numeric(as.character(data_frame$column))
Obwohl andere das Thema ziemlich gut behandelt haben, möchte ich diesen zusätzlichen kurzen Gedanken/Hinweis hinzufügen. Sie können regexp verwenden, um vorab zu überprüfen, ob Zeichen möglicherweise nur aus Zahlen bestehen.
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)
Für ausgefeiltere reguläre Ausdrücke und einen ordentlichen Grund, warum Sie ihre Macht erlernen/erfahren sollten, besuchen Sie diese wirklich schöne Website: http://regexr.com/
Wenn der Datenrahmen mehrere Arten von Spalten hat, einige Zeichen, einige Zahlen, versuchen Sie Folgendes, um nur die Spalten mit numerischen Werten in numerische Werte zu konvertieren:
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])
}
}
In Anbetracht dessen, dass möglicherweise Char-Spalten vorhanden sind, basiert dies auf @Abdou in Excel-Tabellentypen automatisch abrufen :
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)
mit hablar :: convert
Um mehrere Spalten einfach in verschiedene Datentypen zu konvertieren, können Sie hablar::convert
verwenden. Einfache Syntax: df %>% convert(num(a))
konvertiert die Spalte a von df in numerisch.
Detailliertes Beispiel
Wir können alle Spalten von mtcars
in Zeichen konvertieren.
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
Mit hablar::convert
:
library(hablar)
# Convert columns to integer, numeric and factor
df %>%
convert(int(cyl, vs),
num(disp:wt),
fct(gear))
ergebnisse 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
In meinem PC (R v.3.2.3) geben apply
oder sapply
einen Fehler aus. lapply
funktioniert gut.
dt[,2:4] <- lapply(dt[,2:4], function (x) as.factor(as.numeric(x)))
Um ein Zeichen in eine Zahl umzuwandeln, müssen Sie es durch Anwenden in einen Faktor umrechnen
BankFinal1 <- transform(BankLoan, LoanApproval=as.factor(LoanApproval))
BankFinal1 <- transform(BankFinal1, LoanApp=as.factor(LoanApproval))
Sie müssen zwei Spalten mit denselben Daten erstellen, da eine Spalte nicht in numerische Werte umgewandelt werden kann. Wenn Sie eine Konvertierung durchführen, wird der folgende Fehler angezeigt
transform(BankData, LoanApp=as.numeric(LoanApproval))
Warning message: In eval(substitute(list(...)), `_data`, parent.frame()) : NAs introduced by coercion
also, nachdem zwei spalten der gleichen daten gemacht wurden
BankFinal1 < transform(BankFinal1, LoanApp = as.numeric(LoanApp),
LoanApproval = as.numeric(LoanApproval))
das Zeichen wird erfolgreich in eine Zahl umgewandelt