将group_by之后的数据框缩小为一列中的特定值

时间:2018-10-11 14:48:38

标签: r dplyr

我有以下tidyverse问题,用下面的mpg数据集公式化为reprex。

对于每个制造商的每种车型,我想知道是否有6缸版本可用。我可以轻松产生一列six.cyl.available来对该属性进行编码。

library(tidyverse)
df <- mpg %>% mutate(six.cyl.available = if_else(cyl==6, "yes","no"))

reprex package(v0.2.1)于2018-10-11创建

现在,我想通过group_by(manufacturer, model)和 得出一个数据帧,原始帧的所有列都减去“ cyl”。相反,我需要一列six.cyl.available,如果该特定模型可用6缸,则该列包含“是”,否则则包含“否”。像这样:

|manufacturer |model     | displ| year|trans  |drv | cty| hwy|fl |class|six.cyl.available       |
|:------------|:-----------|:----------|---|
|audi         |a4        |   3.1| 2008|auto(av)   |f   |  18|  27|p  |compact    |yes|
|audi         |a4 quattro|   1.8| 1999|manual(m5) |4   |  18|  26|p  |compact    |no|

这个问题让我难过了一段时间。我相信有一个简单的解决方案,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

如果每个组中的所有其他列都具有相同的值,那么如果any列中的cyl有6个,我们可以给出“是”值,那么对于该组,我们返回“是”,否则给出“否” ”,然后从该组中slice中任意一行(在这里我占据第一行),然后从输出中删除cyl列。

library(dplyr)

df %>%
   group_by(manufacturer, model) %>%
   mutate(six.cyl.available = if (any(cyl==6)) "yes" else "no") %>%
   slice(1) %>%
   select(-cyl)

答案 1 :(得分:1)

我的理解是,您正在考虑将模型视为数据集中所有列的唯一组合,因为在所需的输出中不仅包含manufacturermodel列。因此,您想按cyl以外的所有内容对数据框进行分组,然后根据属性的每种组合是否有cyl等于6来汇总数据。

您可以使用group_by_at(vars(-cyl)),例如,要按除 cyl以外的所有列进行分组。调用summarise之后,cyl将被删除,因为它不包含在您的分组中。 ifelse中的summarise可让您设置所需的yes / no列。我使用的是summarise而不是mutate,因为您要在每个组中查找一行。

library(dplyr)

any_six <- ggplot2::mpg %>%
  group_by_at(vars(-cyl)) %>%
  summarise(six.cyl.available = ifelse(any(cyl == 6), "yes", "no"))
print(any_six, width = Inf)
#> # A tibble: 225 x 11
#> # Groups:   manufacturer, model, displ, year, trans, drv, cty, hwy, fl [?]
#>    manufacturer model      displ  year trans      drv     cty   hwy fl   
#>    <chr>        <chr>      <dbl> <int> <chr>      <chr> <int> <int> <chr>
#>  1 audi         a4           1.8  1999 auto(l5)   f        18    29 p    
#>  2 audi         a4           1.8  1999 manual(m5) f        21    29 p    
#>  3 audi         a4           2    2008 auto(av)   f        21    30 p    
#>  4 audi         a4           2    2008 manual(m6) f        20    31 p    
#>  5 audi         a4           2.8  1999 auto(l5)   f        16    26 p    
#>  6 audi         a4           2.8  1999 manual(m5) f        18    26 p    
#>  7 audi         a4           3.1  2008 auto(av)   f        18    27 p    
#>  8 audi         a4 quattro   1.8  1999 auto(l5)   4        16    25 p    
#>  9 audi         a4 quattro   1.8  1999 manual(m5) 4        18    26 p    
#> 10 audi         a4 quattro   2    2008 auto(s6)   4        19    27 p    
#>    class   six.cyl.available
#>    <chr>   <chr>            
#>  1 compact no               
#>  2 compact no               
#>  3 compact no               
#>  4 compact no               
#>  5 compact yes              
#>  6 compact yes              
#>  7 compact yes              
#>  8 compact no               
#>  9 compact no               
#> 10 compact no               
#> # ... with 215 more rows

为了检查是否有意义,我查看了原始数据帧和摘要数据帧的行数。具有相同属性的观测值很少,因此汇总数据框的行数仅比原始数据少。

nrow(ggplot2::mpg)
#> [1] 234
nrow(any_six)
#> [1] 225

reprex package(v0.2.1)于2018-10-11创建