2016-01-01 15 views

Odpowiedz

9

Konwersja z factor na numeric daje wartości całkowite. Ale jeśli kolumny factor mają poziomy określone jako c('b', 'a', 'c', 'd') lub c('c', 'b', 'a'), wartości całkowite będą w tej kolejności. Żeby tego uniknąć, możemy określić levels poprzez ponowne wywołanie factor (bezpieczniej)

df1[] <- lapply(df1, function(x) 
       as.numeric(factor(x, levels=letters[1:3]))) 

Jeśli używamy data.table, jedną z opcji byłoby wykorzystanie set. Byłby bardziej wydajny w przypadku dużych zbiorów danych. Konwertowanie na matrix może powodować problemy z pamięcią.

library(data.table) 
setDT(df1) 
for(j in seq_along(df1)){ 
set(df1, i=NULL, j=j, 
    value= as.numeric(factor(df1[[j]], levels= letters[1:3]))) 
} 
+0

jestem ciekaw: jak jest DF1 [] <- ... Różnią się od DF1 <-... myślę, że prowadzą do tego samego wyniku w końcu, ale może różnymi ścieżkami? – atiretoo

+0

@atiretoo Zachowuje strukturę, tak jak w oryginalnym zbiorze danych. – akrun

+1

Aha! Dzięki tak, w szczególności df1 nadal będzie ramką danych – atiretoo

11

chciałbym spróbować:

> mydf[] <- as.numeric(factor(as.matrix(mydf))) 
> mydf 
    V1 V2 V3 
1 1 2 3 
2 3 2 1 
3 3 2 3 
4 2 2 1 
+0

Czy możesz wyjaśnić, dlaczego prosty "apply (mydf, 2, as.numeric)" nie działa? –

+0

@AlbertMasclans, przeczytaj pierwszy wiersz sekcji "szczegóły" dla "Zastosuj". 'apply' first robi' as.matrix' na 'data.frame' (który zamieni wszystko na' character's). Jeśli użyjesz bezpośrednio 'as.numeric' w wektorze' character', otrzymasz mnóstwo wartości 'NA'. – A5C1D2H2I1M1N2O1R2T1

5

Takie podejście jest podobne do Ananda, ale używa unlist() zamiast factor(as.matrix()). Ponieważ wszystkie kolumny są już czynnikami, unlist() połączy je w jeden wektor czynnikowy z odpowiednimi poziomami.

Zobaczmy więc, co stanie się, gdy będziemy mieć ramkę danych w postaci unlist().

unlist(df, use.names = FALSE) 
# [1] a c c b b b b b c a c a 
# Levels: a b c 

Teraz możemy po prostu uruchomić as.integer() (lub c()) w powyższym kodzie, ponieważ wartości całkowite z czynników dopasować żądany mapowanie. W związku z tym poniższe ponownej oceny całej ramce danych.

df[] <- as.integer(unlist(df, use.names = FALSE)) 
## note that you can also just drop the factor class with c() 
## df[] <- c(unlist(df, use.names = FALSE)) 
df 
# V1 V2 V3 
# 1 1 2 3 
# 2 3 2 1 
# 3 3 2 3 
# 4 2 2 1 

Uwaga:use.names = FALSE nie jest konieczne. Jednak zrzucenie atrybutu nazw spowoduje, że proces ten będzie bardziej wydajny niż nie.

danych:

df <- structure(list(V1 = structure(c(1L, 3L, 3L, 2L), .Label = c("a", 
"b", "c"), class = "factor"), V2 = structure(c(1L, 1L, 1L, 1L 
), .Label = "b", class = "factor"), V3 = structure(c(2L, 1L, 
2L, 1L), .Label = c("a", "c"), class = "factor")), .Names = c("V1", 
"V2", "V3"), class = "data.frame", row.names = c(NA, -4L)) 
Powiązane problemy