it-swarm.com.de

Wie konvertiere ich eine Datenrahmenspalte in einen numerischen Typ?

Wie konvertiert man eine Datenrahmenspalte in einen numerischen Typ?

223
acroa

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! =)

238
aL3xa

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)
120
Jay

wenn x der Spaltenname des Datenrahmens dat ist und x vom Typ Faktor ist, verwenden Sie

as.numeric(as.character(dat$x))
71
user276042

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

19
Somum

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.

14

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

13

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
11
Matt Dancho

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.

11
Gorka

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"
6
Artem Klevtsov

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))
3
Aayush Agrawal

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/

2
Matt Bannert

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])
  }
}
0
Philipp

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)
0
Ferroao

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   
0
davsjob

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)))
0
JKim

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

0
jadhav suraj