Ao usar summarise
com plyr
's ddply
função, categorias vazias são descartados por padrão. Você pode alterar esse comportamento adicionando .drop = FALSE
. No entanto, isso não funciona ao usar summarise
com dplyr
. Existe outra maneira de manter categorias vazias no resultado?
Aqui está um exemplo com dados falsos.
library(dplyr)
df = data.frame(a=rep(1:3,4), b=rep(1:2,6))
# Now add an extra level to df$b that has no corresponding value in df$a
df$b = factor(df$b, levels=1:3)
# Summarise with plyr, keeping categories with a count of zero
plyr::ddply(df, "b", summarise, count_a=length(a), .drop=FALSE)
b count_a
1 1 6
2 2 6
3 3 0
# Now try it with dplyr
df %.%
group_by(b) %.%
summarise(count_a=length(a), .drop=FALSE)
b count_a .drop
1 1 6 FALSE
2 2 6 FALSE
Não é exatamente o que eu esperava. Existe um dplyr
método para alcançar o mesmo resultado que .drop=FALSE
em plyr
?
Respostas:
Já que o dplyr 0.8
group_by
ganhou o.drop
argumento que faz exatamente o que você pediu:Uma observação adicional para acompanhar a resposta de @Moody_Mudskipper: o uso
.drop=FALSE
pode fornecer resultados potencialmente inesperados quando uma ou mais variáveis de agrupamento não são codificadas como fatores. Veja os exemplos abaixo:fonte
count
:iris %>% count(Species, group2, .drop=FALSE)
O problema ainda está aberto, mas enquanto isso, especialmente porque seus dados já estão fatorados, você pode usar
complete
de "tidyr" para obter o que está procurando:Se você quiser que o valor de substituição seja zero, você precisa especificar isso com
fill
:fonte
ungroup()
antes de concluir. Se você perceber quecomplete
não está concluindo,ungroup
provavelmente será necessário.complete(variablewithdroppedlevels, nesting(var1,var2,var3))
(na verdade está na ajuda porquecomplete
ainda levei um tempo para descobrirsolução dplyr:
Primeiro faça df agrupado
então resumimos os níveis que ocorrem contando com
n()
em seguida, mesclamos nossos resultados em um quadro de dados que contém todos os níveis de fator:
finalmente, neste caso, como estamos olhando para contagens, os
NA
valores são alterados para 0.Isso também pode ser implementado funcionalmente, consulte as respostas: Adicionar linhas aos dados agrupados com dplyr?
Um hack:
Pensei em postar um hack terrível que funciona neste caso por uma questão de interesse. Eu duvido seriamente que você deva realmente fazer isso, mas mostra como
group_by()
gera os atributos como sedf$b
fosse um vetor de caracteres e não um fator com níveis. Além disso, não pretendo entender isso corretamente - mas espero que isso me ajude a aprender - esse é o único motivo pelo qual estou postando isso!definir um valor "fora dos limites" que não pode existir no conjunto de dados.
modifique os atributos para "truque"
summarise()
:faça o resumo:
indexe e substitua todas as ocorrências de oob_val
que dá o pretendido:
fonte
isso não é exatamente o que foi perguntado na pergunta, mas pelo menos para este exemplo simples, você poderia obter o mesmo resultado usando xtabs, por exemplo:
usando dplyr:
ou mais curto:
resultado (igual em ambos os casos):
fonte