Q:

Summarise and list custom index in dplyr

I am trying to output grouped summary variables with a corresponding list of identifying variables.  
Using the dplyr::starwars dataset as an example, I would like to calculate number of characters with "light" skin color, grouped by gender, with a vector of names corresponding to each match in a separate output column.  
In the real-world use case, there would be more than one condition to summarise, and the unique identifier could be subjectID/studyID/etc.  I'm open to data.table solutions, prefer solutions that are vector based, R Shiny friendly, easily converted to a function.
Example from 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)
  )

Desired output:
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  

This output would then be tranposed using t() and would use paste() to create a hover-over display of matching names in DT (DataTables).
I'm thinking I need something like
skinname = as.list(.$name[which(skin_color == "light")])

in the summarise step, or possibly a custom function with a do.call in summarise/mutate.

A:

If you want a nested data.frame, you can use 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]>

or if you just want nested vectors, summarize with 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]>

or if you want to keep the empty rows, subset instead of filter:
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]>

If you want to collapse the names down to a single string toString will do the job, but make sure there are no commas in the strings if you plan on separating later.

