在dplyr

时间:2017-07-19 16:01:24

标签: r dplyr summarize

我正在尝试使用相应的标识变量列表输出分组的摘要变量。

使用dplyr::starwars数据集作为示例,我想计算具有“浅色”肤色的字符数,按性别分组,并在单独的输出列中使用与每个匹配对应的名称向量。

在实际使用案例中,summarise会有多个条件,唯一标识符可能是subjectID / studyID /等。我对data.table解决方案持开放态度,更喜欢基于矢量的解决方案,R Shiny友好,易于转换为函数。

来自dplyr::starwars的示例:

starwars %>% 
  filter(species %in% c("Human", "Droid")) %>%
  group_by(gender) %>%
  summarise(
    skin = sum(skin_color=="light", na.rm=T),
    hair = sum(hair_color=="brown", na.rm=T)
  )

期望的输出:

gender skin hair  skinname                                                   hairname
 female  6   6  femname1, femname2, femname3, femname4, femname5, femname6   femhname1, femhname2, femhname3, femhname4, femhname5, femhname6
 male    5   8  mname1, mname2, mname3, mname4, mname5                       mhname1, mhname2, mhname3, mhname4, mhname5, mhname6, mhname7 mhname8
 none    0   0                                                 
 <NA>    0   0  

然后使用t()转换此输出,并使用paste()DT(DataTables)中创建匹配名称的悬停显示。

我想我需要像

这样的东西
skinname = as.list(.$name[which(skin_color == "light")])
<{1>}步骤中的

,或summarise / do.call中可能包含summarise的自定义函数。

1 个答案:

答案 0 :(得分:2)

如果您想要嵌套的data.frame,可以使用tidyr::nest

library(tidyverse)

starwars %>%
    filter(species %in% c("Human", "Droid"), 
           skin_color == 'light') %>%
    group_by(gender) %>% 
    group_by(skin = n(), add = TRUE) %>% 
    nest(name)
#> # A tibble: 2 x 3
#>   gender  skin             data
#>    <chr> <int>           <list>
#> 1 female     6 <tibble [6 x 1]>
#> 2   male     5 <tibble [5 x 1]>

或者如果您只想要嵌套向量,请使用list进行汇总:

starwars %>%
    filter(species %in% c("Human", "Droid"), 
           skin_color == 'light') %>%
    group_by(gender) %>% 
    summarise(skin = n(),
              name = list(name))
#> # A tibble: 2 x 3
#>   gender  skin      name
#>    <chr> <int>    <list>
#> 1 female     6 <chr [6]>
#> 2   male     5 <chr [5]>

或者如果你想保留空行,子集而不是过滤器:

starwars %>% 
    filter(species %in% c("Human", "Droid")) %>%
    group_by(gender) %>%
    summarise(
        skin = sum(skin_color == "light"), 
        name = list(name[skin_color == 'light'])
    )
#> # A tibble: 4 x 3
#>   gender  skin      name
#>    <chr> <int>    <list>
#> 1 female     6 <chr [6]>
#> 2   male     5 <chr [5]>
#> 3   none     0 <chr [0]>
#> 4   <NA>     0 <chr [0]>

如果要将名称折叠为单个字符串toString将执行此任务,但如果您打算稍后分离,请确保字符串中没有逗号。