2016-06-29 13 views
1

Wie kann ich das Delta zwischen mehreren Variablen berechnen, die nach Benutzer-IDs in einem "langen" Datenrahmen gruppiert sind?Berechnung des Deltas zwischen mehreren Variablen, gruppiert nach Benutzer-IDs

Datenformat:

d1 <- data.frame(
    id = rep(c(1, 2, 3, 4, 5), each = 2), 
    purchased = c(rep(c(T, F), 3), F, T, T, F), 
    product = rep(c("A", "B"), 5), 
    grade = c(1, 2, 1, 2, 2, 3, 7, 5, 1, 2), 
    rate = c(10, 12, 10, 12, 12, 14, 22, 18, 10, 12), 
    fee = rep(c(1, 2), 5)) 

Das ist meine Kreisverkehr Lösung:

dA <- d1 %>% 
    filter(product == "A") 

dB <- d1 %>% 
    filter(product == "B") 

d2 <- inner_join(dA, dB, by = "id", suffix = c(".A", ".B")) 

d3 <- d2 %>% 
    mutate(
     purchased = if_else(purchased.A == T, "A", "B"), 
     dGrade = grade.B - grade.A, 
     dRate = rate.B - rate.A, 
     dFee = fee.B - fee.A) %>% 
    select(id, purchased:dFee) 

All dies scheint nur schrecklich ineffizient und komplex. Ist tidyr::spread oder eine andere dplyr/tidyr Funktion hier angebracht? (Ich konnte nichts anderes zum Arbeiten bekommen) ...

Antwort

1

Wir können dies mit gather/spread tun. Ändern Sie die Daten von 'Wide' zu 'Long' mit gather, gruppiert nach 'ID', 'Var', erhalten wir das 'Produkt' basierend auf der logischen Spalte 'gekauft', erhalten Sie die Differenz von 'Val' für 'Produkt' das sind 'B' und 'A', und spread es von 'lang' zu 'breit' Format.

library(dplyr) 
library(tidyr) 
gather(d1, Var, Val, grade:fee) %>% 
      group_by(id, Var) %>% 
      summarise(purchased = product[purchased], 
        Val = Val[product == 'B'] - Val[product == 'A'])%>% 
      spread(Var, Val) 
#  id purchased fee grade rate 
# <dbl> <fctr> <dbl> <dbl> <dbl> 
#1  1   A  1  1  2 
#2  2   A  1  1  2 
#3  3   A  1  1  2 
#4  4   B  1 -2 -4 
#5  5   A  1  1  2 

Die OPs Ausgang ('d3') ist

d3 
# id purchased dGrade dRate dFee 
#1 1   A  1  2 1 
#2 2   A  1  2 1 
#3 3   A  1  2 1 
#4 4   B  -2 -4 1 
#5 5   A  1  2 1 
Verwandte Themen