2015-06-11 15 views
5

Występuje problem z moimi danymi, w którym chcę wziąć pierwszy zaobserwowany ob wynik score dla każdego pojedynczego id i odjąć go od ostatnio obserwowanego score.Wybierz pierwsze obserwowane dane i użyj mutacji

Problem z prośbą o pierwszą obserwację bez ostatniej obserwacji jest taki, że czasami brakuje pierwszych danych obserwacyjnych.

Czy mimo to należy poprosić o pierwszą zaobserwowaną ocenę dla każdej osoby, pomijając w ten sposób brakujące dane?

Zbudowałem poniżej df, aby zilustrować mój problem.

help <- data.frame(id = c(5,5,5,5,5,12,12,12,17,17,20,20,20), 
        ob = c(1,2,3,4,5,1,2,3,1,2,1,2,3), 
        score = c(NA, 2, 3, 4, 3, 7, 3, 4, 3, 4, NA, 1, 4)) 

    id ob score 
1 5 1 NA 
2 5 2  2 
3 5 3  3 
4 5 4  4 
5 5 5  3 
6 12 1  7 
7 12 2  3 
8 12 3  4 
9 17 1  3 
10 17 2  4 
11 20 1 NA 
12 20 2  1 
13 20 3  4 

I co mam nadzieję, że prowadzony jest kod, który da mi ...

id ob score es 
1 5 1 NA -1 
2 5 2  2 -1 
3 5 3  3 -1 
4 5 4  4 -1 
5 5 5  3 -1 
6 12 1  7 3 
7 12 2  3 3 
8 12 3  4 3 
9 17 1  3 -1 
10 17 2  4 -1 
11 20 1 NA -3 
12 20 2  1 -3 
13 20 3  4 -3 

Ja próbuje pracować z dplyr i rozumiem użycie polecenia „group_by”, jednak nie wiesz, jak "wybrać" tylko pierwsze obserwowane wyniki, a następnie zmutować, aby utworzyć es.

Odpowiedz

6

użyłbym first() i last() (zarówno dplyr funkcja) i na.omit() (z pakietu statystyki domyślne.

Po pierwsze, chciałbym się upewnić, kolumna Twój wynik był numeryczna kolumna z odpowiednimi wartościami Na (nie ciągi jak w Twój przykład)

help <- data.frame(id = c(5,5,5,5,5,12,12,12,17,17,20,20,20), 
     ob = c(1,2,3,4,5,1,2,3,1,2,1,2,3), 
     score = c(NA, 2, 3, 4, 3, 7, 3, 4, 3, 4, NA, 1, 4)) 

wtedy można zrobić

library(dplyr) 
help %>% group_by(id) %>% arrange(ob) %>% 
    mutate(es=first(na.omit(score)-last(na.omit(score)))) 
+0

Kiedy uruchomić ten kod na moich rzeczywistych danych, pojawia się błąd -> „Błąd: Don” t wiedzieć, jak wygenerować domyślne dla obiektu klasy numerycznej ". Zmienne są liczbowe i istnieje spora liczba NA, np. niektóre id mają tylko NA, a inne nie. jakieś pomysły? – bpace

+0

Jeśli nie masz nic oprócz wartości NA, co chcesz zwrócić? Byłoby miło, gdyby twoje przykładowe dane zawierały ten scenariusz wraz z pożądanym wynikiem. – MrFlick

+0

Uzgodnione. Zatem problem polega na tym, że istnieją 3 różne zmienne dla wyniku, a każdy identyfikator ma wynik dla jednej z trzech zmiennych. Zakładam, że mogę uruchomić kod dla każdego z nich, ale jeśli id ​​w group_by nie ma danych dla partytury, to pojawia się komunikat o błędzie ... prawdopodobnie dlatego, że na.omit usuwa wszystkie dane, a tam nie ma nic do odejmowania. – bpace

0

to rozwiązanie jest Litt le gadatliwy tylko b/c to opiera się na kilku funkcjach pomocniczych FIRST i LAST:

# The position (indicator) of the first value that evaluates to TRUE. 
LAST <- function (x, none = NA) { 
    out <- FIRST(reverse(x), none = none) 
    if (identical(none, out)) { 
     return(none) 
    } 
    else { 
     return(length(x) - out + 1) 
    } 
} 
# The position (indicator) of the last value that evaluates to TRUE. 
FIRST <- function (x, none = NA) 
{ 
    x[is.na(x)] <- FALSE 
    if (any(x)) 
     return(which.max(x)) 
    else return(none) 
} 

# returns the difference between the first and last non-missing values 
diff2 <- function(x) 
    x[LAST(!is.na(x))] - x[FIRST(!is.na(x))] 


library(dplyr) 
help %>% 
    group_by(id) %>% 
    arrange(ob) %>% 
     summarise(diff = diff2(score)) 
1
library(dplyr) 

temp <- help %>% group_by(id) %>% 
    arrange(ob) %>% 
    filter(!is.na(score)) %>% 
    mutate(es = first(score) - last(score)) %>% 
    select(id, es) %>% 
    distinct() 

help %>% left_join(temp)