2014-05-13 10 views
5

Byłbym wdzięczny za pomoc w następującym zadaniu: Z poniższej ramki danych (C), dla każdego id chciałbym odjąć pierwszy wpis pod kolumną d_2 od ostatecznego wejdź, a następnie zapisz wyniki w innej ramce danych zawierającej te same identyfikatory. Mogę następnie połączyć to z moją początkową ramką danych. Pls zauważ, że odejmowanie musi być w tej kolejności (ostatnie wejście minus pierwszy wpis dla każdego id).Jak odjąć pierwszy wpis z ostatniego wpisu w zgrupowanych danych

Oto kody:

id <- c("A1", "A1", "B10","B10", "B500", "B500", "C100", "C100", "C100", "D40", "D40", "G100", "G100") 

d_1 <- c(rep(1.15, 2), rep(1.44, 2), rep(1.34, 2), rep(1.50, 3), rep(1.90, 2), rep(1.59, 2)) 

set.seed(2) 

d_2 <- round(runif(13, -1, 1), 2) 

C <- data.frame(id, d_1, d_2) 

id d_1 d_2 
A1 1.15 -0.63 
A1 1.15 0.40 
B10 1.44 0.15 
B10 1.44 -0.66 
B500 1.34 0.89 
B500 1.34 0.89 
C100 1.50 -0.74 
C100 1.50 0.67 
C100 1.50 -0.06 
D40 1.90 0.10 
D40 1.90 0.11 
G100 1.59 -0.52 
G100 1.59 0.52 

Pożądany wynik:

id2 <- c("A1", "B10", "B500", "C100", "D40", "G100") 

difference <- c(1.03, -0.81, 0, 0.68, 0.01, 1.04) 

diff_df <- data.frame(id2, difference) 

id2 difference 
A1  1.03 
B10  -0.81 
B500  0.00 
C100  0.68 
D40  0.01 
G100  1.04 

próbowałem to za pomocą ddply aby uzyskać pierwsze i ostatnie wpisy, ale jestem naprawdę borykają się z indeksowania „funkcji argument "w drugim kodzie (poniżej), aby uzyskać pożądany wynik.

C_1 <- ddply(C, .(id), function(x) x[c(1, nrow(x)), ]) 

ddply(C_1, .(patient), function) 

Szczerze mówiąc, nie jestem bardzo obeznany z ddply pakietu-Dostałem powyższy kod z innego post na wymianie stosu.

Mój oryginalny danych jest groupedData i wierzę inny sposób zbliża ten korzysta gapply ale znowu jestem zmaga się z trzecim argumentem tutaj (zazwyczaj funkcję)

grouped_C <- groupedData(d_1 ~ d_2 | id, data = C, FUN = mean, labels = list(x = "", y = ""), units = list("")) 

x1 <- gapply(grouped_C, "d_2", first_entry) 

x2 <- gapply(grouped_C, "d_2", last_entry) 

gdzie first_entry i last_entry są funkcjami aby pomóc mi uzyskać pierwsze i ostatnie wpisy. Mogę wtedy uzyskać różnicę z: x2 - x1. Jednak nie jestem pewien, co wpisać jako first_entry i last_entry w powyższych kodach (może zrobić z głową lub ogonem?).

Każda pomoc będzie mile widziana.

Odpowiedz

7

Można to łatwo zrobić przy pomocy dplyr. Funkcje last i first są bardzo pomocne w tym zadaniu.

library(dplyr)    #install the package dplyr and load it into library 

diff_df <- C %>%    #create a new data.frame (diff_df) and store the output of the following operation in it. The %.% operator is used to chain several operations together but you dont have to reference the data.frame you are using each time. so here we are using your data.frame C for the following steps 
    group_by(id) %>%   #group the whole data.frame C by id 
    summarize(difference = last(d_2)-first(d_2))  #for each group of id, create a single line summary where the first entry of d_2 (for that group) is subtracted from the last entry of d_2 for that group 

# id difference    #this is the result stored in diff_df 
#1 A1  1.03 
#2 B10  -0.81 
#3 B500  0.00 
#4 C100  0.68 
#5 D40  0.01 
#6 G100  1.04 

Edit uwaga: zaktualizowane post z %>% zamiast %.% która jest nieaktualna.

+0

Dzięki za odpowiedź, bardzo cenione. Czy możesz wyjaśnić składnię i różne części kodu? itp. Jest to mój pierwszy raz przy użyciu tego pakietu. –

+1

@John Pewnie. Dodałem komentarze, aby wyjaśnić operacje w mojej odpowiedzi. Aby uzyskać więcej informacji na temat 'dplyr', zapoznaj się z tym wprowadzeniem do pakietu (http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html) –

+0

@ beginneR-fajne imię przy okazji! Dziękuję bardzo, komentarze były bardzo pomocne, ale przejdę również przez dokumentację. Dzięki! –

0

Jeśli masz jedno singletons i trzeba zostawić je w spokoju, rozwiąże to twój problem. Jest taka sama jak odpowiedź docendo discimus, ale ze składnikiem if-else do czynienia z pojedynczych przypadkach:

library(dplyr)    
diff_df <- C %>%    
    group_by(id) %>% 
    summarize(difference = if(n() > 1) last(d_2) - first(d_2) else d_2) 
Powiązane problemy