Was ist der schnellste / beste Weg, um eine große Anzahl von Spalten vom Faktor in einen numerischen zu ändern?
Ich habe den folgenden Code verwendet, aber er scheint meine Daten neu geordnet zu haben.
> head(stats[,1:2])
rk team
1 1 Washington Capitals*
2 2 San Jose Sharks*
3 3 Chicago Blackhawks*
4 4 Phoenix Coyotes*
5 5 New Jersey Devils*
6 6 Vancouver Canucks*
for(i in c(1,3:ncol(stats))) {
stats[,i] <- as.numeric(stats[,i])
}
> head(stats[,1:2])
rk team
1 2 Washington Capitals*
2 13 San Jose Sharks*
3 24 Chicago Blackhawks*
4 26 Phoenix Coyotes*
5 27 New Jersey Devils*
6 28 Vancouver Canucks*
Was ist der beste Weg, ohne jede Spalte wie folgt zu benennen:
df$colname <- as.numeric(ds$colname)
Antworten:
Nach Ramnaths Antwort ist das Verhalten, das Sie erleben, das Ergebnis der
as.numeric(x)
Rückgabe der internen numerischen Darstellung des Faktorsx
auf der R-Ebene. Wenn Sie die Zahlen beibehalten möchten, die die Ebenen des Faktors darstellen (und nicht deren interne Darstellung), müssen Sieas.character()
gemäß Ramnaths Beispiel zuerst in Zeichen konvertieren .Ihre
for
Schleife ist genauso vernünftig wie einapply
Aufruf und möglicherweise etwas besser lesbar, was die Absicht des Codes ist. Ändern Sie einfach diese Zeile:lesen
Dies ist FAQ 7.10 in den R FAQ.
HTH
quelle
factor
und es hat nicht funktioniert.sapply
odermutate_if
scheinen allgemein anwendbare Lösungen zu sein.apply
die Schleife ausführt und das OPfor
explizit eine Schleife verwendet. Tatsächlich verwenden alle hoch bewerteten Antworten dieas.numeric(as.character())
Redewendung.numeric
, aber es funktioniert nicht umgekehrt (um die Klasse mehrerer Spalten in zu ändernfactor
). Wenn Sie benötigte Indizes verwendenunlist()
und diese auf Spalten mit Zeichen anwenden, werden alle einzelnen Zeichen aufgelistet, sodass sie beim Zurücksetzen der Ausgabe nicht mehr funktionierenstats[,i]
. Überprüfen Sie die Antwort hier: stackoverflow.com/questions/45713473/…as.factor()
anstelle vonas.numeric(as.character())
hier und es wird gut funktionieren. Natürlich, wenn Sie eine Mischung von Spalten haben, müssen Siei
selektiv auswählen , aber das ist auch trivial.Sie müssen vorsichtig sein, wenn Sie Faktoren in numerische ändern. Hier ist eine Codezeile, die eine Reihe von Spalten von Faktor zu Numerisch ändert. Ich gehe hier davon aus, dass die Spalten, die in numerisch geändert werden sollen, 1, 3, 4 bzw. 5 sind. Sie können es entsprechend ändern
cols = c(1, 3, 4, 5); df[,cols] = apply(df[,cols], 2, function(x) as.numeric(as.character(x)));
quelle
x<-as.factor(1:3); df<-data.frame(a=x,y=runif(3),b=x,c=x,d=x)
. Ich denke nicht, dassapply
das für diese Art von Problemen angemessen ist.apply
. Überprüfen Sie meine Bearbeitung.unlist
. Eineas.character
Konvertierung in Ihrer Lösung ist nicht erforderlich, da dieapply
Konvertierungdf[,cols]
incharacter
soapply(df[,cols], 2, function(x) as.numeric(x))
auch funktioniert.=
? Warum nicht<-
?Dies kann in einer Zeile erfolgen, es ist keine Schleife erforderlich, sei es eine for-Schleife oder eine Anwendung. Verwenden Sie stattdessen unlist ():
# testdata Df <- data.frame( x = as.factor(sample(1:5,30,r=TRUE)), y = as.factor(sample(1:5,30,r=TRUE)), z = as.factor(sample(1:5,30,r=TRUE)), w = as.factor(sample(1:5,30,r=TRUE)) ) ## Df[,c("y","w")] <- as.numeric(as.character(unlist(Df[,c("y","w")]))) str(Df)
Bearbeiten: Für Ihren Code wird dies:
id <- c(1,3:ncol(stats))) stats[,id] <- as.numeric(as.character(unlist(stats[,id])))
Wenn Sie einen einspaltigen Datenrahmen haben und nicht möchten, dass die automatische Dimensionsreduktion von R ihn in einen Vektor konvertiert, müssen Sie das
drop=FALSE
Argument hinzufügen .quelle
recursive
unduse.names
Parameter vonunlist
beiden seinFALSE
.Df <- tibble::as_tibble(Df)
mutate_if
. Oder welcher neue Ansatz auch immer in der nächsten Iteration vondplyr
...Ich weiß, dass diese Frage schon lange gelöst ist, aber ich hatte kürzlich ein ähnliches Problem und denke, ich habe eine etwas elegantere und funktionalere Lösung gefunden, obwohl dafür das magrittr-Paket erforderlich ist.
library(magrittr) cols = c(1, 3, 4, 5) df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))
Der
%<>%
Bediener leitet und weist neu zu, was sehr nützlich ist, um die Datenbereinigung und -transformation einfach zu halten. Jetzt ist die Listenanwendungsfunktion viel einfacher zu lesen, indem nur die Funktion angegeben wird, die Sie anwenden möchten.quelle
df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))
df[,cols] %<>% as.numeric(as.character(.))
die gleiche funktioniertError in [.data.table(Results, , cols) : j (the 2nd argument inside [...]) is a single symbol but column name 'cols' is not found. Perhaps you intended DT[,..cols] or DT[,cols,with=FALSE]. This difference to data.frame is deliberate and explained in FAQ 1.1.
cols <- c("a","b"); df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))
Hier sind einige
dplyr
Optionen:# by column type: df %>% mutate_if(is.factor, ~as.numeric(as.character(.))) # by specific columns: df %>% mutate_at(vars(x, y, z), ~as.numeric(as.character(.))) # all columns: df %>% mutate_all(~as.numeric(as.character(.)))
quelle
Ich denke, dass ucfagls herausgefunden hat, warum Ihre Schleife nicht funktioniert.
Falls Sie immer noch keine Schleife verwenden möchten, finden Sie hier eine Lösung mit
lapply
:factorToNumeric <- function(f) as.numeric(levels(f))[as.integer(f)] cols <- c(1, 3:ncol(stats)) stats[cols] <- lapply(stats[cols], factorToNumeric)
Bearbeiten. Ich habe eine einfachere Lösung gefunden. Es scheint, dass
as.matrix
in Charakter konvertieren. Damitsollte tun was du willst.
quelle
lapply ist so ziemlich dafür konzipiert
unfactorize<-c("colA","colB") df[,unfactorize]<-lapply(unfactorize, function(x) as.numeric(as.character(df[,x])))
quelle
Ich habe diese Funktion in einigen anderen doppelten Threads gefunden und eine elegante und allgemeine Möglichkeit gefunden, dieses Problem zu lösen. Dieser Thread wird bei den meisten Suchanfragen zu diesem Thema zuerst angezeigt, daher teile ich ihn hier, um den Leuten Zeit zu sparen. Ich nehme das nicht gut, nur siehe die Originalbeiträge hier und hier für Details.
df <- data.frame(x = 1:10, y = rep(1:2, 5), k = rnorm(10, 5,2), z = rep(c(2010, 2012, 2011, 2010, 1999), 2), j = c(rep(c("a", "b", "c"), 3), "d")) convert.magic <- function(obj, type){ FUN1 <- switch(type, character = as.character, numeric = as.numeric, factor = as.factor) out <- lapply(obj, FUN1) as.data.frame(out) } str(df) str(convert.magic(df, "character")) str(convert.magic(df, "factor")) df[, c("x", "y")] <- convert.magic(df[, c("x", "y")], "factor")
quelle
Ich möchte darauf hinweisen, dass die einfache Verwendung von Indizes nicht funktioniert, wenn Sie NAs in einer Spalte haben. Wenn der Faktor NAs enthält, müssen Sie das von Ramnath bereitgestellte Apply-Skript verwenden.
Z.B
Df <- data.frame( x = c(NA,as.factor(sample(1:5,30,r=T))), y = c(NA,as.factor(sample(1:5,30,r=T))), z = c(NA,as.factor(sample(1:5,30,r=T))), w = c(NA,as.factor(sample(1:5,30,r=T))) ) Df[,c(1:4)] <- as.numeric(as.character(Df[,c(1:4)]))
Gibt Folgendes zurück:
Warning message: NAs introduced by coercion > head(Df) x y z w 1 NA NA NA NA 2 NA NA NA NA 3 NA NA NA NA 4 NA NA NA NA 5 NA NA NA NA 6 NA NA NA NA
Aber:
Df[,c(1:4)]= apply(Df[,c(1:4)], 2, function(x) as.numeric(as.character(x)))
Kehrt zurück:
> head(Df) x y z w 1 NA NA NA NA 2 2 3 4 1 3 1 5 3 4 4 2 3 4 1 5 5 3 5 5 6 4 2 4 4
quelle
Sie können die
unfactor()
Funktion aus dem "varhandle" -Paketformular CRAN verwenden:library("varhandle") my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length), sample_id = factor(1:nrow(iris))) my_iris <- unfactor(my_iris)
quelle
Ich mag diesen Code, weil er ziemlich praktisch ist:
data[] <- lapply(data, function(x) type.convert(as.character(x), as.is = TRUE)) #change all vars to their best fitting data type
Es ist nicht genau das, wonach gefragt wurde (in numerisch konvertieren), aber in vielen Fällen sogar noch angemessener.
quelle
df$colname <- as.numeric(df$colname)
Ich habe auf diese Weise versucht, einen Spaltentyp zu ändern, und ich denke, es ist besser als viele andere Versionen, wenn Sie nicht alle Spaltentypen ändern
df$colname <- as.character(df$colname)
für umgekehrt.
quelle
Ich hatte Probleme, alle Spalten mit einem
apply()
Aufruf in numerische zu konvertieren :apply(data, 2, as.numeric)
Das Problem stellt sich heraus, dass einige der Zeichenfolgen ein Komma enthielten - z. B. "1.024,63" anstelle von "1024,63" - und R diese Art der Formatierung von Zahlen nicht mag. Also habe ich sie entfernt und bin dann gelaufen
as.numeric()
:data = as.data.frame(apply(data, 2, function(x) { y = str_replace_all(x, ",", "") #remove commas return(as.numeric(y)) #then convert }))
Beachten Sie, dass hierfür das stringr-Paket geladen werden muss.
quelle
Das hat bei mir funktioniert. Die
apply()
Funktion versucht, df zur Matrix zu zwingen, und gibt NAs zurück.numeric.df <- as.data.frame(sapply(df, 2, as.numeric))
quelle
Basierend auf der Antwort von @ SDahm war dies eine "optimale" Lösung für meine
tibble
:Dies erfordert
dplyr
undmagrittr
.quelle
Ich habe ein paar davon bei einem ähnlichen Problem ausprobiert und immer wieder NAs bekommen. Base R hat einige wirklich irritierende Zwangsverhalten, die im Allgemeinen in Tidyverse-Paketen festgelegt sind. Früher habe ich sie vermieden, weil ich keine Abhängigkeiten erstellen wollte, aber sie machen das Leben so viel einfacher, dass ich mich jetzt die meiste Zeit nicht mehr darum kümmere, die Base R-Lösung herauszufinden.
Hier ist die Tidyverse-Lösung, die äußerst einfach und elegant ist:
library(purrr) mydf <- data.frame( x1 = factor(c(3, 5, 4, 2, 1)), x2 = factor(c("A", "C", "B", "D", "E")), x3 = c(10, 8, 6, 4, 2)) map_df(mydf, as.numeric)
quelle
as.numeric(as.character())
Konvertierung durchgeführt wird, um die allzu häufige Konvertierung von Ganzzahlstufen anstelle von Werten in numerische Werte zu vermeiden . Ich würde diese Antwort gerne positiv bewerten, wenn Sie diese Option zeigen.