Podczas korzystania summarise
z plyr
„s ddply
funkcji, puste kategorie są odrzucane domyślnie. Możesz zmienić to zachowanie, dodając .drop = FALSE
. Jednak to nie działa w przypadku korzystania summarise
z dplyr
. Czy jest inny sposób na zachowanie pustych kategorii w wyniku?
Oto przykład z fałszywymi danymi.
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
Nie do końca to, na co liczyłem. Czy istnieje dplyr
metoda osiągnięcia takiego samego wyniku jak .drop=FALSE
w plyr
?
Odpowiedzi:
Ponieważ dplyr 0.8
group_by
uzyskał.drop
argument, który robi dokładnie to, o co prosiłeś:Dodatkowa uwaga związana z odpowiedzią @ Moody_Mudskipper: użycie
.drop=FALSE
może dać potencjalnie nieoczekiwane wyniki, gdy jedna lub więcej zmiennych grupujących nie jest zakodowanych jako czynniki. Zobacz przykłady poniżej:źródło
count
:iris %>% count(Species, group2, .drop=FALSE)
Problem jest nadal otwarty, ale w międzyczasie, zwłaszcza że Twoje dane są już uwzględnione, możesz użyć
complete
z „tidyr”, aby uzyskać to, czego szukasz:Jeśli chcesz, aby wartość zastąpienia wynosiła zero, musisz to określić za pomocą
fill
:źródło
ungroup()
przed ukończeniem. Jeśli kiedykolwiek zauważysz, że wcomplete
rzeczywistości nie ukończono,ungroup
prawdopodobnie jest to potrzebne.complete(variablewithdroppedlevels, nesting(var1,var2,var3))
(tak naprawdę jest w pomocy, ponieważcomplete
zajęło mi to jeszcze trochę czasurozwiązanie dplyr:
Najpierw utwórz zgrupowane df
następnie podsumowujemy występujące poziomy licząc z
n()
następnie scalamy nasze wyniki w ramkę danych zawierającą wszystkie poziomy czynników:
na koniec w tym przypadku, ponieważ patrzymy na zliczenia,
NA
wartości są zmieniane na 0.Można to również zaimplementować funkcjonalnie, patrz odpowiedzi: Dodać wiersze do zgrupowanych danych za pomocą dplyr?
Hack:
Pomyślałem, że opublikuję okropny hack, który działa w tym przypadku ze względu na zainteresowanie. Poważnie wątpię, żebyś kiedykolwiek to zrobił, ale pokazuje, jak
group_by()
generuje atrybuty, jakbydf$b
wektor znakowy, a nie czynnik z poziomami. Poza tym nie udaję, że dobrze to rozumiem - ale mam nadzieję, że to pomoże mi się nauczyć - to jedyny powód, dla którego to publikuję!zdefiniuj wartość „poza zakresem”, która nie może istnieć w zbiorze danych.
zmień atrybuty na „oszukanie”
summarise()
:zrób podsumowanie:
zindeksuj i zamień wszystkie wystąpienia oob_val
co daje zamierzone:
źródło
nie jest to dokładnie to, o co pytano w pytaniu, ale przynajmniej w tym prostym przykładzie możesz uzyskać ten sam wynik za pomocą xtabs, na przykład:
używając dplyr:
lub krócej:
wynik (równy w obu przypadkach):
źródło