Выберите значение в group_by и суммируйте на основе другого значения столбца в R - PullRequest
0 голосов
/ 02 января 2019

В следующем примере, как выбрать значение (из mpg) для группы (cyl) в зависимости от условия в другом столбце (carb == 1). Обратите внимание, что я также хочу суммировать другую переменную (в среднем qsec на группу). Мое лучшее предположение ниже получает ошибку:

library(dplyr)
mtcars %>% 
    distinct(cyl, carb, .keep_all = TRUE) %>% 
    group_by(cyl) %>% 
    summarize(
        mpg = mpg[.$carb == 1],
        qsec = mean(qsec)
    )

1 Ответ

0 голосов
/ 02 января 2019

Если существует более одной строки с 'carb', равным 1, и summarise возвращает только одну строку на группу или без какой-либо группы, то лучше обернуть вывод в list. Если мы используем $, это нарушит группировку

library(tidyverse)
out <- mtcars %>% 
        distinct(cyl, carb, .keep_all = TRUE) %>% 
        group_by(cyl) %>% 
        summarize(
          mpg = list(mpg[carb == 1]),
          qsec = mean(qsec)
        ) 

out
# A tibble: 3 x 3
#    cyl mpg        qsec
#  <dbl> <list>    <dbl>
#1     4 <dbl [1]>  19.3
#2     6 <dbl [1]>  17.1
#3     8 <dbl [0]>  16.2

Если посмотреть на результат, то для 'cyl' 8 нет 'carb', равного 1. В результате получается numeric(0)

Обтягивая replace_na, элементы длины 0 можно изменить на NA, а затем сделать unnest. В противном случае, как упоминал @Dave Gruenewald в комментариях, эта строка может быть удалена автоматически при unnest ing

out %>% 
  mutate(mpg = replace_na(mpg)) %>% 
  unnest
# A tibble: 3 x 3
#    cyl  qsec   mpg
#  <dbl> <dbl> <dbl>
#1     4  19.3  22.8
#2     6  17.1  21.4
#3     8  16.2  NA  

Другой вариант, если мы уже знаем, что будет не более 1 элемента 'carb', равного 1, тогда используйте условие if/else в summarise

mtcars %>%
    distinct(cyl, carb, .keep_all = TRUE) %>% 
    group_by(cyl) %>%
    summarise(
       mpg = if(any(carb == 1)) mpg[carb==1] else NA_real_,
       qsec = mean(qsec)
 )
# A tibble: 3 x 3
#     cyl   mpg  qsec
#   <dbl> <dbl> <dbl>
#1     4  22.8  19.3
#2     6  21.4  17.1
#3     8  NA    16.2

Однако лучше предположить, что может быть более одного значения «карбюратора», равного 1 для каждого «цил», и обернуть его в list, позже unnest

mtcars %>%
    distinct(cyl, carb, .keep_all = TRUE) %>% 
    group_by(cyl) %>%
    summarise(
       mpg = list(if(any(carb == 1)) mpg[carb==1] else NA_real_),
       qsec = mean(qsec)) %>%
    unnest
...