Wat is de snelste/beste manier om een groot aantal kolommen van factor naar numeriek te veranderen?
Ik heb de volgende code gebruikt, maar het lijkt erop dat mijn gegevens opnieuw zijn gerangschikt.
> 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*
Wat is de beste manier, behalve elke kolom een naam te geven zoals in:
df$colname <- as.numeric(ds$colname)
Antwoord 1, autoriteit 100%
Je moet voorzichtig zijn bij het wijzigen van factoren in numeriek. Hier is een regel code die een reeks kolommen zou veranderen van factor in numeriek. Ik neem hier aan dat de kolommen die moeten worden gewijzigd in numeriek respectievelijk 1, 3, 4 en 5 zijn. Je zou het dienovereenkomstig kunnen wijzigen
cols = c(1, 3, 4, 5);
df[,cols] = apply(df[,cols], 2, function(x) as.numeric(as.character(x)));
Antwoord 2, autoriteit 77%
Vervolgens Ramnath’s antwoord, is het gedrag dat u ervaart het gevolg van het feit dat as.numeric(x)
de interne, numerieke representatie van de factor x
aan de R retourneert niveau. Als je de getallen wilt behouden die de niveaus van de factor zijn (in plaats van hun interne representatie), moet je eerst converteren naar teken via as.character()
volgens het voorbeeld van Ramnath.
Je for
-lus is net zo redelijk als een apply
-aanroep en is misschien iets beter leesbaar wat de bedoeling van de code is. Verander gewoon deze regel:
stats[,i] <- as.numeric(stats[,i])
om te lezen
stats[,i] <- as.numeric(as.character(stats[,i]))
Dit is FAQ 7.10in de R FAQ.
HTH
Antwoord 3, autoriteit 54%
Dit kan in één regel worden gedaan, er is geen lus nodig, of het nu een for-lus of een toepassing is. Gebruik in plaats daarvan 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)
Bewerken: voor uw code wordt dit:
id <- c(1,3:ncol(stats)))
stats[,id] <- as.numeric(as.character(unlist(stats[,id])))
Als u een dataframe met één kolom heeft en u wilt niet dat de automatische dimensiereductie van R deze omzet in een vector, moet u uiteraard de drop=FALSE
toevoegen argument.
Antwoord 4, autoriteit 43%
Ik weet dat deze vraag al lang is opgelost, maar ik had onlangs een soortgelijk probleem en ik denk dat ik een iets elegantere en functionelere oplossing heb gevonden, hoewel het magrittr-pakket vereist is.
library(magrittr)
cols = c(1, 3, 4, 5)
df[,cols] %<>% lapply(function(x) as.numeric(as.character(x)))
De operator %<>%
leidt enopnieuw toe, wat erg handig is om het opschonen en transformeren van gegevens eenvoudig te houden. Nu is de lijsttoepassingsfunctie veel gemakkelijker te lezen, door alleen de functie op te geven die u wilt toepassen.
Antwoord 5, autoriteit 20%
Hier zijn enkele dplyr
opties:
# 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(.)))
Antwoord 6, autoriteit 8%
Ik denk dat ucfagls heeft gevonden waaromuw loop niet werkt.
Als je nog steeds geen lus wilt gebruiken, is hier een oplossing met lapply
:
factorToNumeric <- function(f) as.numeric(levels(f))[as.integer(f)]
cols <- c(1, 3:ncol(stats))
stats[cols] <- lapply(stats[cols], factorToNumeric)
Bewerken. Ik heb een eenvoudigere oplossing gevonden. Het lijkt erop dat as.matrix
converteert naar karakter. Dus
stats[cols] <- as.numeric(as.matrix(stats[cols]))
moet doen wat je wilt.
Antwoord 7, autoriteit 7%
Lapply is hier min of meer voor ontworpen
unfactorize<-c("colA","colB")
df[,unfactorize]<-lapply(unfactorize, function(x) as.numeric(as.character(df[,x])))
Antwoord 8, autoriteit 3%
Ik vond deze functie in een paar andere dubbele threads en vond het een elegante en algemene manier om dit probleem op te lossen. Deze thread verschijnt als eerste bij de meeste zoekopdrachten over dit onderwerp, dus ik deel het hier om mensen wat tijd te besparen. Ik neem hier geen eer voor, dus bekijk de originele berichten hieren hiervoor 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")
Antwoord 9
Ik wil erop wijzen dat als je NA’s in een kolom hebt, het gebruik van subscripts niet werkt. Als er NA’s in de factor zijn, moet u het toepassingsscript van Ramnath gebruiken.
Bijvoorbeeld
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)]))
Retourneert het volgende:
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
Maar:
Df[,c(1:4)]= apply(Df[,c(1:4)], 2, function(x) as.numeric(as.character(x)))
Retouren:
> 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
Antwoord 10
u kunt de functie unfactor()
gebruiken uit het pakket “varhandle” van CRAN:
library("varhandle")
my_iris <- data.frame(Sepal.Length = factor(iris$Sepal.Length),
sample_id = factor(1:nrow(iris)))
my_iris <- unfactor(my_iris)
11
df$colname <- as.numeric(df$colname)
Ik probeerde op deze manier voor het veranderen van het type één kolom en ik denk dat het beter dan vele andere versies, als je niet van plan om alle soorten kolom te veranderen
df$colname <- as.character(df$colname)
voor de vice versa.