/ / porównaj wartość zagregowaną w różnych grupach - r, dplyr

porównaj wartość zagregowaną w różnych grupach - r, dplyr

Z df poniżej,

  1. trzeba obliczyć medianę dla zmiennej metric w zespołach tm1, tm2 i tm3 na per locid, day, hour podstawa combo
  2. następnie filtruj tylko te locid, day, hour obserwacje, które mają takie same metric mediana między zespołami tm1, tm2, tm3.

    set.seed(100)
    df <- data.frame(
    locid = sample(c(1111,1122,1133), 20, replace=TRUE),
    day = sample(c(1:3), 20, replace=TRUE),
    hour = sample(c(1:4), 20, replace=TRUE),
    team = sample(c("tm1", "tm2", "tm3"), 20, replace=TRUE),
    metric = sample(1:5, 20, replace=TRUE )
    )
    

moja próba

df_medians <- df %>%
group_by(locid + day + hour + team) %>%
summarise(metric_median = median(metric))

to daje median za team dla każdego locid + day + hour. Muszę się teraz dowiedzieć locid + day + hour kombinacje, które dają taką samą medianę w zespołach tm1, tm2, tm3.

df_medians %>% group_by(locid, day, hour, team) %>% summarise(??what here??)

Próbowałem z dplyr, ale rozwiązanie bazowe jest w porządku.

Jako prostszy przykład możemy spojrzeć na poniższe dane, które mają pomiary z dwóch różnych lokalizacji dla dwóch zespołów.

+-------+------+-------+-------+---------+
| locid |  day |  hour |  team |  metric |
+-------+------+-------+-------+---------+
|  1111 |    1 |     1 |  tm1  |       3 |
|  1111 |    1 |     1 |  tm1  |       2 |
|  1111 |    1 |     1 |  tm1  |       1 |

|  1111 |    1 |     1 |  tm2  |       1 |
|  1111 |    1 |     1 |  tm2  |       2 |
|  1111 |    1 |     1 |  tm2  |       3 |

|  1122 |    1 |     1 |  tm1  |       3 |
|  1122 |    1 |     1 |  tm1  |       2 |
|  1122 |    1 |     1 |  tm1  |       1 |

|  1122 |    1 |     1 |  tm2  |       1 |
|  1122 |    1 |     1 |  tm2  |       2 |
|  1122 |    1 |     1 |  tm2  |       1 |
+-------+------+-------+-------+---------+

krok 1 - oblicz medianę według grupy

+-------+------+-------+-------+-------------+
| locid |  day |  hour |  team |  metric_med |
+-------+------+-------+-------+-------------+
|  1111 |    1 |     1 |  tm1  |       2     |
|  1111 |    1 |     1 |  tm2  |       2     |
|  1122 |    1 |     1 |  tm1  |       2     |
|  1122 |    1 |     1 |  tm2  |       1     |
+-------+------+-------+-------+-------------+

Krok 2 - porównaj mediany w grupie (locid + dzień + godzina) tylko (1111, 1, 1) ma to samo metric_med we wszystkich zespołach gp1 i gp2

+-------+------+-------+-------------+
| locid |  day |  hour |  metric_med |
+-------+------+-------+-------------+
|  1111 |    1 |     1 |       2     |
+-------+------+-------+-------------+

Odpowiedzi:

0 dla odpowiedzi № 1

Jednym ze sposobów jest rozłożenie grup na jeden wiersz na każdy locid, dzień i godzinę, a następnie porównanie ich. Rozwiązanie to skaluje się dobrze dla więcej niż dwóch grup i skomplikowanych warunków.

library(dplyr)
library(tidyr)

data %>%
group_by(locid, day, hour, team) %>%
summarize(median = median(metric)) %>%
spread(team, median) %>%
filter(tm1 == tm2)

Innym możliwym rozwiązaniem jest uporządkowanie podsumowanych wyników według lokalizacji, dnia i godziny, a następnie porównanie mediany w jednym rzędzie z jej lag. To rozwiązanie działa tylko dla dwóch grup w zespole.

data %>%
group_by(locid, day, hour, team) %>%
summarize(median = median(metric)) %>%
arrange(locid, day, hour) %>%
filter(median == lag(median))

0 dla odpowiedzi nr 2

Ponownie prześlijmy „wszystko równe”, co oznacza „zerową wariancję lub pojedynczą obserwację”.

df %>% # per locid, day, hour, team group_by(locid, day, hour, team) %>% # compute median summarize(team_median = median(metric)) %>% # ungroup before specifying new grouping ungroup %>% # for locid, day, hour group_by(locid, day, hour) %>% # find the medians that were the same for all teams # "the same" here is taken to mean no variance # or having a single observation # note that, although logical vector TRUE | NA does yield TRUE # this is only because it must yield TRUE. # As another example, FALSE | NA, yields NA. # As a guard against team_medians that are NA, I add a coalesce wrapper. # I"ve decided that missing team_medians represent non-cases, YMMV summarize(all_equal = coalesce(n() == 1 | var(team_median) == 0), FALSE) %>% filter(all_equal == TRUE) %>% select(-all_equal)