Есть ли элегантный способ разделить результаты двух резюме друг с другом? - PullRequest
4 голосов
/ 02 февраля 2020

У меня есть два фрейма данных ww и pp, которые выглядят так:

> dput(ww)
structure(list(W_GEW = c(10.2353040126845, 0.831884443723177, 
0.0575388010226499, 1.32932249946475, 2.13545328158608, 1.50612800756816, 
2.41411532240417, 0.272920801750955, 3.79195336455684, 0.450693179969236, 
0.883654166531408, 0.603534664687679, 0.198110485099713, 0.342652280675876, 
0.289928028243725, 6.48435880991905, 0.95407351540347, 8.05653638220527, 
2.28316474679988, 0.487760497903453, 0.224996354463327, 0.553435733400469, 
0.330192354360254, 0.0876946359196857, 1.70203606555473), HP_SEX = c(2, 
2, 1, 2, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 
2, 1, 1)), row.names = c(NA, -25L), class = c("tbl_df", "tbl", 
"data.frame"))
> dput(pp)
structure(list(P_GEW = c(0.576128482078767, 1.25180927581909, 
0.102502993629535, 1.35359813678368, 1.56322227704677, 0.692845851279203, 
0.387225241732726, 6.42061013929398, 1.06395274428815, 1.17730952115625, 
1.57374838709105, 6.32338670691465, 1.12358902975024, 0.559852743148847, 
0.244938631158, 0.342884568546086, 0.166101271235082, 1.32857499401104, 
0.898931543979382, 0.830611859630472, 0.822265711424057, 0.183075471978817, 
3.67290388261628, 0.149252785037704, 0.523294953428612), HP_SEX = c(1, 
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 
2, 1, 1)), row.names = c(NA, -25L), class = c("tbl_df", "tbl", 
"data.frame"))

Мой первый шаг - сгруппировать фреймы данных по HP_SEX и суммировать их следующим образом:

> ww %>% 
+   group_by(HP_SEX) %>%
+   summarise(W_GEW = sum(W_GEW))
# A tibble: 2 x 2
  HP_SEX W_GEW
   <dbl> <dbl>
1      1  22.1
2      2  24.4
> pp %>% 
+   group_by(HP_SEX) %>%
+   summarise(P_GEW = sum(P_GEW)) 
# A tibble: 2 x 2
  HP_SEX P_GEW
   <dbl> <dbl>
1      1  12.4
2      2  21.0

Мой следующий шаг - это разделить W_GEW на P_GEW, разделенный HP_SEX, следующим образом:

22.1/12.4 = 1.78

24.4/21.0 = 1.16

Я выгляжу ios, если есть элегантный способ сделать это за один шаг или с одной функцией.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 02 февраля 2020

Один из способов может быть:

ww %>% 
 group_by(HP_SEX) %>%
 summarise(W_GEW = sum(W_GEW)) %>%
 left_join(pp %>% 
            group_by(HP_SEX) %>%
            summarise(P_GEW = sum(P_GEW)), by = c("HP_SEX" = "HP_SEX")) %>%
 mutate(GEW = W_GEW/P_GEW)

  HP_SEX W_GEW P_GEW   GEW
   <dbl> <dbl> <dbl> <dbl>
1      1  22.1  12.4  1.79
2      2  24.4  21.0  1.16
1 голос
/ 02 февраля 2020

Мы можем поместить наборы данных в list, а затем сделать группу по сумме в list, reduce его в одном наборе данных и выполнить деление

library(dplyr)
library(purrr)
map(lst(ww, pp), ~ .x %>%
                      group_by(HP_SEX) %>% 
                      summarise_at(vars(-group_cols()), sum)) %>% 
      reduce(inner_join) %>% 
      mutate(GEW = W_GEW/P_GEW)
# A tibble: 2 x 4
#  HP_SEX W_GEW P_GEW   GEW
#   <dbl> <dbl> <dbl> <dbl>
#1      1  22.1  12.4  1.79
#2      2  24.4  21.0  1.16

Также, если некоторые шаги можно использовать повторно, затем можно создать функцию

f1 <- function(dat, grp) {
         dat %>% 
            group_by({{grp}}) %>%
            summarise_at(vars(-group_cols()), sum)
 }

map(list(ww, pp), f1, grp = HP_SEX) %>% 
     reduce(inner_join) %>% 
     mutate(GEW = W_GEW/P_GEW)

или с помощью base R

transform(Reduce(merge, lapply(list(ww, pp), 
   function(dat) aggregate(.~ HP_SEX, dat, sum))), GEW = W_GEW/P_GEW)
#   HP_SEX    W_GEW    P_GEW      GEW
#1      1 22.13622 12.38124 1.787884
#2      2 24.37122 20.95138 1.163228
0 голосов
/ 03 февраля 2020

Базовая версия R ответа @ tmfmnk будет использовать aggregate, merge и transform

transform(merge(aggregate(P_GEW~HP_SEX, pp, sum), 
                aggregate(W_GEW~HP_SEX, ww, sum)), ans = W_GEW/P_GEW)

#  HP_SEX    P_GEW    W_GEW      ans
#1      1 12.38124 22.13622 1.787884
#2      2 20.95138 24.37122 1.163228
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...