2012-02-27 13 views
5

Mam data.frame, która zawiera kilka czynników i chcę zmienić nazwy poziomów czynników dla wszystkich tych czynników. Np .:Jak przypisać w ramach stosowania rodziny?

mydf <- data.frame(col1 = as.factor(c("A","A",NA,NA)),col2 = as.factor(c("A",NA,NA,"A"))) 
mydf <- as.data.frame(lapply(mydf,addNA)) 

Należy pamiętać, że rzeczywisty przykład życia ma znacznie więcej niż dwie kolumny. Stąd chciałbym użyć zastosować przypisać inne nazwy szczebla do wszystkich tych kolumn, tak jak w:

levels(mydf$col1) <- c("1","0") 

Próbowałem następujących ale to nie działa ...

apply(mydf,1,function(x) levels(x) <- c("1","0")) 

nie jestem naprawdę zaskoczony, że to nie działa, ale nie mam teraz żadnych lepszych pomysłów. Czy powinienem używać with?

EDYCJA: Zdałem sobie sprawę, że popełniłem tu błąd, upraszczając rzeczy. Użyłem addNA, aby uwzględnić fakt, że NA nie powinny już być traktowane jako NA. Dlatego też chcę zmienić ich etykietę. ta nie działa z sugestią Andrie i zwraca następujący komunikat o błędzie:

labels = c("1", : invalid labels; length 2 should be 1 or 1 

pamiętać, że zaktualizowany moim przykładzie DF.

+0

Nie mówisz, co chcesz zrobić z poziomami NA. Zmień ich nazwy na co? – Andrie

+0

po użyciu addNA Mam poziomy 1 i . I lubię, aby kategoria NA została przemianowana na 0 - tak jak były to zwykłe poziomy czynników i nigdy nie były NA. –

+0

@Charles: co jest złego w tagu kategorycznym? To jest poważne pytanie. Czy to dlatego, że jest agnostykiem językowym? Użycie wyrażenia R dla kategorycznego ("czynnik") nie byłoby lepsze. Czy powinienem zostawić cały aspekt i dlaczego? –

Odpowiedz

8

Możesz zmieniać poziomy, korzystając z numerów setattr() z pakietów bit lub data.table. W ten sposób unika kopiując cały zestaw danych, a skoro mówiłeś, że masz dużo kolumn ...

require(bit)   # Either package 
require(data.table) # 
setattr(mydf[[1]],"levels",c("1","0")) 
setattr(mydf[[2]],"levels",c("1","0")) 

Można to zrobić w prosty for pętli, który jest bardzo szybki. Twoim obowiązkiem jest, abyś zastąpił wektor poziomów wektorem o tej samej długości, w przeciwnym razie czynnik może nie być już ważny. I musisz zastąpić cały wektor poziomów tą metodą. Istnieje wewnętrzna droga w data.table, aby zastąpić poszczególne nazwy poziomów przez odniesienie, ale prawdopodobnie nie trzeba iść tak daleko.

+1

Dlaczego nie 'attr (mydf [[1]]," levels ") <- c (" 1 "," 0 ")' lub 'levels (mydf [[1]]) <- c (" 1 "," 0 ")'? –

+2

@ Joshu 'tracemem (mydf)' najpierw zobacz 4 kopie (obiektu _whole_). Zachowaj 'tracemem', a następnie wypróbuj' setattr() ': żadnych kopii, żadnych. Następnie podaj 'mydf' 1 miliard wierszy i obserwuj, jak inne kończą się z' out of memory', kiedy 'setattr()' działa dobrze (i szybko). –

+0

Ach, oczywiście, ponieważ podporządkowujesz element data.frame. Moje testy na pojedynczym wektorze nie tworzyły kopii. Dziękuję za wyjaśnienie. –