Dplyr: Precisa ser capaz de amostrar grupos

Criado em 28 mar. 2014  ·  9Comentários  ·  Fonte: tidyverse/dplyr

Bem como indivíduos dentro de grupos

Comentários muito úteis

A resposta acima por @drhagen parece estar desatualizada. Isso parece funcionar agora:

sample_n_groups = function(tbl, size, replace = FALSE, weight = NULL) {
  # regroup when done
  grps = tbl %>% groups %>% lapply(as.character) %>% unlist
  # check length of groups non-zero
  keep = tbl %>% summarise() %>% ungroup() %>% sample_n(size, replace, weight)
  # keep only selected groups, regroup because joins change count.
  # regrouping may be unnecessary but joins do something funky to grouping variable
  tbl %>% right_join(keep, by=grps) %>% group_by_(.dots = grps)
}

Todos 9 comentários

species <- iris %.% 
  group_by(Species) %.% 
  summarise(wt = sum(Sepal.Length)) %.%
  sample_n(5, replace = T, weight = wt) %.%
  select(-wt)

inner_join(species, iris)

Eu me pergunto por que isso foi fechado? Parece ser um recurso potencialmente útil

iris %>%
    group_by(Species) %>%
    sample_n(1)

para pegar todos os dados de uma espécie aleatória, por exemplo

Não acho que o comportamento de sample_n deva mudar para grupos porque a amostragem dentro dos grupos é seu comportamento intuitivo. No entanto, geralmente é útil poder amostrar grupos como um todo. Esta deve ser uma segunda função. Aqui está minha implementação:

sample_n_groups = function(tbl, size, replace = FALSE, weight=NULL) {
   # regroup when done
   grps = tbl %>% groups %>% unlist %>% as.character
   # check length of groups non-zero
   keep = tbl %>% summarise() %>% sample_n(size, replace, weight)
   # keep only selected groups, regroup because joins change count.
   # regrouping may be unnecessary but joins do something funky to grouping variable
   tbl %>% semi_join(keep) %>% group_by_(grps) 
}

O exemplo de @rcorty funciona apenas o esperado

iris %>% group_by(Species) %>% sample_n_groups(1)

+1

Editar: uma mudança em dplyr quebrou esta solução;


Para aqueles de vocês que chegaram aqui através do mecanismo de busca em busca dessa funcionalidade, a implementação por @MarcusWalz não faz a amostragem com substituição quando replace = TRUE . A implementação precisa usar right_join (ou left_join ou inner_join ) para manter as duplicatas:

sample_n_groups = function(tbl, size, replace = FALSE, weight=NULL) {
  # regroup when done
  grps = tbl %>% groups %>% unlist %>% as.character
  # check length of groups non-zero
  keep = tbl %>% summarise() %>% sample_n(size, replace, weight)
  # keep only selected groups, regroup because joins change count.
  # regrouping may be unnecessary but joins do something funky to grouping variable
  tbl %>% right_join(keep, by=grps) %>% group_by_(grps) 
}

A inicialização de cluster é um caso de uso amplo para esse recurso.

@drhagen , em sua implementação, você tem alguma sugestão de como gerar um novo id de grupo exclusivo?

Na verdade, isso é muito fácil:

sample_n_groups = function(tbl, size, replace = FALSE, weight=NULL) {
  # regroup when done
  grps = tbl %>% groups %>% unlist %>% as.character
  # check length of groups non-zero
  keep = tbl %>% summarise() %>% sample_n(size, replace, weight) %>% 
    mutate(unique_id = 1:NROW(.))
  # keep only selected groups, regroup because joins change count.
  # regrouping may be unnecessary but joins do something funky to grouping variable
  tbl %>% right_join(keep, by=grps) %>% group_by_(grps) 
}

A resposta acima por @drhagen parece estar desatualizada. Isso parece funcionar agora:

sample_n_groups = function(tbl, size, replace = FALSE, weight = NULL) {
  # regroup when done
  grps = tbl %>% groups %>% lapply(as.character) %>% unlist
  # check length of groups non-zero
  keep = tbl %>% summarise() %>% ungroup() %>% sample_n(size, replace, weight)
  # keep only selected groups, regroup because joins change count.
  # regrouping may be unnecessary but joins do something funky to grouping variable
  tbl %>% right_join(keep, by=grps) %>% group_by_(.dots = grps)
}
Esta página foi útil?
0 / 5 - 0 avaliações