dplyr 요약 : 출력에서 길이가 0 인 그룹을 유지하려면 ".drop = FALSE"와 동일합니다.
summarise
with plyr
의 ddply
함수를 사용하면 기본적으로 빈 카테고리가 삭제됩니다. 을 추가하여이 동작을 변경할 수 있습니다 .drop = FALSE
. 그러나 .NET summarise
과 함께 사용할 때는 작동하지 않습니다 dplyr
. 결과에서 빈 범주를 유지하는 다른 방법이 있습니까?
다음은 가짜 데이터가있는 예입니다.
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
내가 바랬던 것과는 다릅니다. dplyr
에서와 같은 결과를 얻을 수 있는 방법 .drop=FALSE
이 plyr
있습니까?
이후 dplyr 0.8 group_by
음이온의 .drop
당신이 요구하는 일 인수를 :
df = data.frame(a=rep(1:3,4), b=rep(1:2,6))
df$b = factor(df$b, levels=1:3)
df %>%
group_by(b, .drop=FALSE) %>%
summarise(count_a=length(a))
#> # A tibble: 3 x 2
#> b count_a
#> <fct> <int>
#> 1 1 6
#> 2 2 6
#> 3 3 0
@Moody_Mudskipper의 답변과 함께 가야 할 추가 참고 사항 : .drop=FALSE
하나 이상의 그룹화 변수가 요인으로 코딩되지 않은 경우을 사용하면 예상치 못한 결과가 발생할 수 있습니다. 아래 예를 참조하십시오.
library(dplyr)
data(iris)
# Add an additional level to Species
iris$Species = factor(iris$Species, levels=c(levels(iris$Species), "empty_level"))
# Species is a factor and empty groups are included in the output
iris %>% group_by(Species, .drop=FALSE) %>% tally
#> Species n
#> 1 setosa 50
#> 2 versicolor 50
#> 3 virginica 50
#> 4 empty_level 0
# Add character column
iris$group2 = c(rep(c("A","B"), 50), rep(c("B","C"), each=25))
# Empty groups involving combinations of Species and group2 are not included in output
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally
#> Species group2 n
#> 1 setosa A 25
#> 2 setosa B 25
#> 3 versicolor A 25
#> 4 versicolor B 25
#> 5 virginica B 25
#> 6 virginica C 25
#> 7 empty_level <NA> 0
# Turn group2 into a factor
iris$group2 = factor(iris$group2)
# Now all possible combinations of Species and group2 are included in the output,
# whether present in the data or not
iris %>% group_by(Species, group2, .drop=FALSE) %>% tally
#> Species group2 n
#> 1 setosa A 25
#> 2 setosa B 25
#> 3 setosa C 0
#> 4 versicolor A 25
#> 5 versicolor B 25
#> 6 versicolor C 0
#> 7 virginica A 0
#> 8 virginica B 25
#> 9 virginica C 25
#> 10 empty_level A 0
#> 11 empty_level B 0
#> 12 empty_level C 0
Created on 2019-03-13 by the reprex package (v0.2.1)
문제는 여전히 열려 있지만 그 동안 특히 데이터가 이미 complete
팩토링되었으므로 "tidyr"에서 사용 하여 원하는 것을 얻을 수 있습니다.
library(tidyr)
df %>%
group_by(b) %>%
summarise(count_a=length(a)) %>%
complete(b)
# Source: local data frame [3 x 2]
#
# b count_a
# (fctr) (int)
# 1 1 6
# 2 2 6
# 3 3 NA
대체 값이 0이되도록하려면 다음을 사용하여 지정해야합니다 fill
.
df %>%
group_by(b) %>%
summarise(count_a=length(a)) %>%
complete(b, fill = list(count_a = 0))
# Source: local data frame [3 x 2]
#
# b count_a
# (fctr) (dbl)
# 1 1 6
# 2 2 6
# 3 3 0
dplyr 솔루션 :
먼저 그룹화 된 df 만들기
by_b <- tbl_df(df) %>% group_by(b)
다음으로 계산하여 발생하는 수준을 요약합니다. n()
res <- by_b %>% summarise( count_a = n() )
그런 다음 모든 요인 수준을 포함하는 데이터 프레임에 결과를 병합합니다.
expanded_res <- left_join(expand.grid(b = levels(df$b)),res)
마지막으로,이 경우 카운트를보고 있으므로 NA
값이 0으로 변경됩니다.
final_counts <- expanded_res[is.na(expanded_res)] <- 0
This can also be implemented functionally, see answers: Add rows to grouped data with dplyr?
A hack:
I thought I would post a terrible hack that works in this case for interest's sake. I seriously doubt you should ever actually do this but it shows how group_by()
generates the atrributes as if df$b
was a character vector not a factor with levels. Also, I don't pretend to understand this properly -- but I am hoping this helps me learn -- this is the only reason I'm posting it!
by_b <- tbl_df(df) %>% group_by(b)
define an "out-of-bounds" value that cannot exist in dataset.
oob_val <- nrow(by_b)+1
modify attributes to "trick" summarise()
:
attr(by_b, "indices")[[3]] <- rep(NA,oob_val)
attr(by_b, "group_sizes")[3] <- 0
attr(by_b, "labels")[3,] <- 3
do the summary:
res <- by_b %>% summarise(count_a = n())
index and replace all occurences of oob_val
res[res == oob_val] <- 0
which gives the intended:
> res
Source: local data frame [3 x 2]
b count_a
1 1 6
2 2 6
3 3 0
this is not exactly what was asked in the question, but at least for this simple example, you could get the same result using xtabs, for example:
using dplyr:
df %>%
xtabs(formula = ~ b) %>%
as.data.frame()
or shorter:
as.data.frame(xtabs( ~ b, df))
result (equal in both cases):
b Freq
1 1 6
2 2 6
3 3 0
'IT박스' 카테고리의 다른 글
GitHub에서 프로젝트 다운로드 수를 확인하는 방법은 무엇입니까? (0) | 2020.09.04 |
---|---|
OpenSSL : PEM 루틴 : PEM_read_bio : 시작 줄 없음 : pem_lib.c : 703 : 예상 : TRUSTED CERTIFICATE [닫힘] (0) | 2020.09.04 |
프로덕션 환경에서 스프링 부트 실행 가능 jar를 어떻게 실행합니까? (0) | 2020.09.04 |
배열에서 clone ()을 호출해도 내용이 복제됩니까? (0) | 2020.09.04 |
Meteor에는 어떤 보안 메커니즘이 있습니까? (0) | 2020.09.04 |