2012-06-08 14 views
10

Tak więc, ma ramkę danych z dwóch elementów i jedną zmienną numerycznej tak:Obsługa brakujących kombinacje czynników R

>D 
f1 f2 v1 
1 A 23 
2 A 45 
2 B 27 
    . 
    . 
    . 

więc poziom f1 oznaczają 1 i 2, a także poziomy f2 są A i B. Tutaj jest rzecz, nie ma wartości wprowadzonej dla kiedy f1 = 1 i f2 = B (to jest D $ V1 [D $ f1 = 1 & D $ f2 = B] nie ma) w rzeczywistości powinno to być zero.

W mojej aktualnej ramce danych mam 11 poziomów f1 i blisko 150 poziomów f2 i muszę utworzyć obserwację z v1 = 0 dla każdej kombinacji f1 i f2, której brakuje w mojej ramce danych.

Jak miałbym to zrobić?

Dzięki z góry,

Ian

Odpowiedz

11

Korzystanie swoje dane:

dat <- data.frame(f1 = factor(c(1,2,2)), f2 = factor(c("A","A","B")), 
        v1 = c(23,45,27)) 

Jedną z opcji jest utworzyć tabelę przeglądową z kombinacji poziomów, które odbywa się za pomocą funkcji expand.grid() dostarczonego z poziomami obu czynników, jak pokazano poniżej:

dat2 <- with(dat, expand.grid(f1 = levels(f1), f2 = levels(f2))) 

Baza danych, jak dołączyć operację można następnie przeprowadzić przy użyciu funkcji merge(), w którym określamy, że wszystkie wartości z tabeli przeglądowej są zawarte w sprzężeniu (all.y = TRUE)

newdat <- merge(dat, dat2, all.y = TRUE) 

Powyższa linia produkuje:

> newdat 
    f1 f2 v1 
1 1 A 23 
2 1 B NA 
3 2 A 45 
4 2 B 27 

Jak widać, brakujące kombinacje otrzymują wartość NA wskazującą brakującą wartość. Jest realtively prosta następnie zastąpić te NA S z 0 s:

> newdat$v1[is.na(newdat$v1)] <- 0 
> newdat 
    f1 f2 v1 
1 1 A 23 
2 1 B 0 
3 2 A 45 
4 2 B 27 
+0

@ user1443010 w tej linii, używam go, aby uniknąć 'dat $ f1' i' dat $ f2'. Myślę też, że to czyni zamiar jasnym; używając * tego * obiektu, wykonaj * to *. Nie ma nic złego w tym na poziomie użytkownika, ale istnieje kara za wydajność, ponieważ R musi stworzyć nowe środowisko z zawartością obiektu, a to wymaga czasu. 'dat2 <- expand.grid (f1 = poziomy (dat $ f1), f2 = poziomy (dat $ f2)) byłyby alternatywą. Nie zawsze można pracować z '' z() '; Nie sądzę, aby linia zastępująca "NA" mogła zostać łatwo przekształcona w 'with()', ale może mi brakować czegoś. –

+0

niesamowite! dzięki! ;) – maycca

1

Dwa lata późno, ale miałem ten sam problem i wpadł na ten plyr rozwiązania:

dat <- data.frame(f1 = factor(c(1,2,2)), f2 = factor(c("A","A","B")), v1 = c(23,45,27)) 

newdat <- ddply(dat, .(f1,f2), numcolwise(function(x) {if(length(x)>0) x else 0.0}), .drop=F) 

> newdat 
    f1 f2 v1 
1 1 A 23 
2 1 B 0 
3 2 A 45 
4 2 B 27 
2

dodam tidyr rozwiązanie, rozprzestrzeniając się z fill=0 i zbierając.

library(tidyr) 
df %>% spread(f2, v1, fill=0) %>% gather(f2, v1, -f1) 

# f1 f2 v1 
#1 1 A 23 
#2 2 A 45 
#3 1 B 0 
#4 2 B 27 

Można również zrobić df %>% spread(f1, v1, fill=0) %>% gather(f1, v1, -f2).

Powiązane problemy