dplyr을 사용한 상대 빈도/비율
각 그룹 내에서 서로 다른 값의 비율을 계산하려고 합니다.예를 들어, 다음을 사용합니다.mtcars데이터, 암(자동/수동)에 의한 기어 수의 상대 주파수를 어떻게 계산합니까?dplyr?
library(dplyr)
data(mtcars)
mtcars <- tbl_df(mtcars)
# count frequency
mtcars %>%
group_by(am, gear) %>%
summarise(n = n())
# am gear n
# 0 3 15
# 0 4 4
# 1 4 8
# 1 5 5
달성하고자 하는 목표:
am gear n rel.freq
0 3 15 0.7894737
0 4 4 0.2105263
1 4 8 0.6153846
1 5 5 0.3846154
사용해 보십시오.
mtcars %>%
group_by(am, gear) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n))
# am gear n freq
# 1 0 3 15 0.7894737
# 2 0 4 4 0.2105263
# 3 1 4 8 0.6153846
# 4 1 5 5 0.3846154
dplyrvignet에서:
여러 변수로 그룹화하면 각 요약이 그룹화의 한 수준에서 벗겨집니다.따라서 데이터 세트를 점진적으로 롤업하기가 쉽습니다.
그러므로, 그 후에.summarise지정된 마지막 그룹화 변수group_by'기어'가 벗겨집니다.에서mutate단계에서 데이터는 나머지 그룹화 변수(여기서 'am')별로 그룹화됩니다.각 단계에서 그룹화를 확인할 수 있습니다.groups.
필링의 결과는 물론 그룹화 변수의 순서에 따라 달라집니다.group_by호출합니다. 다음 단계를 수행할 수 있습니다.group_by(am)코드를 보다 명확하게 표시합니다.
라운딩과 프레이팅은 @Tyler Lincer의 멋진 답변을 참고하시기 바랍니다.
사용할 수 있습니다.count()그러나 버전에 따라 다른 동작을 갖는 함수dplyr:
dplyr 0.7.1: 그룹화되지 않은 테이블을 반환합니다. 다음 기준으로 다시 그룹화해야 합니다.
amdplyr < 0.7.1: 그룹화된 테이블을 반환하므로 다시 그룹화할 필요가 없습니다.
ungroup()추후의 조작을 위하여.
dplyr 0.7.1
mtcars %>%
count(am, gear) %>%
group_by(am) %>%
mutate(freq = n / sum(n))
dplyr < 0.7.1
mtcars %>%
count(am, gear) %>%
mutate(freq = n / sum(n))
그러면 그룹화된 테이블이 생성됩니다. 추가 분석에 사용하려면 그룹화된 속성을 제거하는 것이 유용할 수 있습니다.ungroup().
@헨릭은 열 문자가 더 이상 숫자가 아니라 요청한 내용과 일치하기 때문에 유용성에 더 좋습니다.
mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = paste0(round(100 * n/sum(n), 0), "%"))
## am gear n rel.freq
## 1 0 3 15 79%
## 2 0 4 4 21%
## 3 1 4 8 62%
## 4 1 5 5 38%
스페이스맨이 요청했기 때문에 편집 :-)
as.rel_freq <- function(x, rel_freq_col = "rel.freq", ...) {
class(x) <- c("rel_freq", class(x))
attributes(x)[["rel_freq_col"]] <- rel_freq_col
x
}
print.rel_freq <- function(x, ...) {
freq_col <- attributes(x)[["rel_freq_col"]]
x[[freq_col]] <- paste0(round(100 * x[[freq_col]], 0), "%")
class(x) <- class(x)[!class(x)%in% "rel_freq"]
print(x)
}
mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = n/sum(n)) %>%
as.rel_freq()
## Source: local data frame [4 x 4]
## Groups: am
##
## am gear n rel.freq
## 1 0 3 15 79%
## 2 0 4 4 21%
## 3 1 4 8 62%
## 4 1 5 5 38%
많은 답변에도 불구하고, 다음과 같은 방법을 사용합니다.prop.table'dplyr' 또는 'data.table'과 함께 사용할 수 있습니다.
'dplyr' v. >= 1.1.0 이후 우리는 다음을 사용할 수 있습니다..by에 있어서의 논쟁.mutate:
library(dplyr)
mtcars %>%
count(am, gear) %>%
mutate(freq = prop.table(n), .by = am)
#> am gear n freq
#> 1 0 3 15 0.7894737
#> 2 0 4 4 0.2105263
#> 3 1 4 8 0.6153846
#> 4 1 5 5 0.3846154
dplyr v. < 1.1.0> 이전의 한 가지 접근 방식은 다음과 같습니다.
mtcars %>%
group_by(am, gear) %>%
tally() %>%
mutate(freq = prop.table(n))
#> # A tibble: 4 × 4
#> # Groups: am [2]
#> am gear n freq
#> <dbl> <dbl> <int> <dbl>
#> 1 0 3 15 0.789
#> 2 0 4 4 0.211
#> 3 1 4 8 0.615
#> 4 1 5 5 0.385
'data.table'을 사용하면 다음을 수행할 수 있습니다.
library(data.table)
cars_dt <- as.data.table(mtcars)
cars_dt[, .(n = .N), keyby = .(am, gear)][, freq := prop.table(n), by = "am"][]
#> am gear n freq
#> 1: 0 3 15 0.7894737
#> 2: 0 4 4 0.2105263
#> 3: 1 4 8 0.6153846
#> 4: 1 5 5 0.3846154
repref v2.0.2를 사용하여 2022-10-22에 생성됨
이 반복 작업을 위해 작은 함수를 작성했습니다.
count_pct <- function(df) {
return(
df %>%
tally %>%
mutate(n_pct = 100*n/sum(n))
)
}
그런 다음 다음과 같이 사용할 수 있습니다.
mtcars %>%
group_by(cyl) %>%
count_pct
반환되는 항목:
# A tibble: 3 x 3
cyl n n_pct
<dbl> <int> <dbl>
1 4 11 34.4
2 6 7 21.9
3 8 14 43.8
이 인기 있는 질문의 완전성을 위해 버전 1.0.0 이후dplyrparameter .groups는 그룹화 구조를 제어합니다.summarise 뒤에 합니다.group_by 도움말을 요약합니다.
와 함께.groups = "drop_last",summarise그룹화의 마지막 수준을 삭제합니다.이것은 버전 1.0.0 이전에 얻은 유일한 결과입니다.
library(dplyr)
library(scales)
original <- mtcars %>%
group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = scales::percent(n/sum(n), accuracy = 0.1))
#> `summarise()` regrouping output by 'am' (override with `.groups` argument)
original
#> # A tibble: 4 x 4
#> # Groups: am [2]
#> am gear n rel.freq
#> <dbl> <dbl> <int> <chr>
#> 1 0 3 15 78.9%
#> 2 0 4 4 21.1%
#> 3 1 4 8 61.5%
#> 4 1 5 5 38.5%
new_drop_last <- mtcars %>%
group_by (am, gear) %>%
summarise (n=n(), .groups = "drop_last") %>%
mutate(rel.freq = scales::percent(n/sum(n), accuracy = 0.1))
dplyr::all_equal(original, new_drop_last)
#> [1] TRUE
와 함께.groups = "drop"모든 그룹화 수준이 삭제됩니다.결과는 이전의 흔적이 없는 독립적인 경골로 바뀝니다.group_by
# .groups = "drop"
new_drop <- mtcars %>%
group_by (am, gear) %>%
summarise (n=n(), .groups = "drop") %>%
mutate(rel.freq = scales::percent(n/sum(n), accuracy = 0.1))
new_drop
#> # A tibble: 4 x 4
#> am gear n rel.freq
#> <dbl> <dbl> <int> <chr>
#> 1 0 3 15 46.9%
#> 2 0 4 4 12.5%
#> 3 1 4 8 25.0%
#> 4 1 5 5 15.6%
한다면.groups = "keep"이 mtcarsdata와 동일한 그룹 구조(이 경우 mtcars). summarise는 서사용변제않습니다거에 하지 않습니다.group_by.
마막으로와 함께..groups = "rowwise"각 행은 고유한 그룹입니다.은 이 에서 "하는 것과 .
# .groups = "keep"
new_keep <- mtcars %>%
group_by (am, gear) %>%
summarise (n=n(), .groups = "keep") %>%
mutate(rel.freq = scales::percent(n/sum(n), accuracy = 0.1))
new_keep
#> # A tibble: 4 x 4
#> # Groups: am, gear [4]
#> am gear n rel.freq
#> <dbl> <dbl> <int> <chr>
#> 1 0 3 15 100.0%
#> 2 0 4 4 100.0%
#> 3 1 4 8 100.0%
#> 4 1 5 5 100.0%
# .groups = "rowwise"
new_rowwise <- mtcars %>%
group_by (am, gear) %>%
summarise (n=n(), .groups = "rowwise") %>%
mutate(rel.freq = scales::percent(n/sum(n), accuracy = 0.1))
dplyr::all_equal(new_keep, new_rowwise)
#> [1] TRUE
관심을 가질 수 있는 또 다른 점은 때때로 적용한 후에group_by그리고.summarise요약 행이 도움이 될 수 있습니다.
# create a subtotal line to help readability
subtotal_am <- mtcars %>%
group_by (am) %>%
summarise (n=n()) %>%
mutate(gear = NA, rel.freq = 1)
#> `summarise()` ungrouping output (override with `.groups` argument)
mtcars %>% group_by (am, gear) %>%
summarise (n=n()) %>%
mutate(rel.freq = n/sum(n)) %>%
bind_rows(subtotal_am) %>%
arrange(am, gear) %>%
mutate(rel.freq = scales::percent(rel.freq, accuracy = 0.1))
#> `summarise()` regrouping output by 'am' (override with `.groups` argument)
#> # A tibble: 6 x 4
#> # Groups: am [2]
#> am gear n rel.freq
#> <dbl> <dbl> <int> <chr>
#> 1 0 3 15 78.9%
#> 2 0 4 4 21.1%
#> 3 0 NA 19 100.0%
#> 4 1 4 8 61.5%
#> 5 1 5 5 38.5%
#> 6 1 NA 13 100.0%
reprex 패키지(v0.3.0)에 의해 2020-11-09에 생성되었습니다.
이 답변이 유용하기를 바랍니다.
Henrik의 솔루션을 구현하는 일반적인 기능은 다음과 같습니다.dplyr0.7.1.
freq_table <- function(x,
group_var,
prop_var) {
group_var <- enquo(group_var)
prop_var <- enquo(prop_var)
x %>%
group_by(!!group_var, !!prop_var) %>%
summarise(n = n()) %>%
mutate(freq = n /sum(n)) %>%
ungroup
}
또한 (pesky group_by.groups 주위를 둘러보세요).
mtcars %>%
count(am, gear) %>%
add_count(am, wt = n, name = "nn") %>%
mutate(proportion = n / nn)
에 다은음사기용한본다니입 R변답음다를 사용한 R.aggregate그리고.ave:
df1 <- with(mtcars, aggregate(list(n = mpg), list(am = am, gear = gear), length))
df1$prop <- with(df1, n/ave(n, am, FUN = sum))
#Also with prop.table
#df1$prop <- with(df1, ave(n, am, FUN = prop.table))
df1
# am gear n prop
#1 0 3 15 0.7894737
#2 0 4 4 0.2105263
#3 1 4 8 0.6153846
#4 1 5 5 0.3846154
우리는 또한 사용할 수 있습니다.prop.table그러나 출력이 다르게 표시됩니다.
prop.table(table(mtcars$am, mtcars$gear), 1)
# 3 4 5
# 0 0.7894737 0.2105263 0.0000000
# 1 0.0000000 0.6153846 0.3846154
이 대답은 마티푸의 대답을 바탕으로 한 것입니다.
먼저 scipen 옵션을 사용하여 freq 열이 과학적 표기 열로 반환되지 않도록 수정했습니다.
그런 다음 답에 100을 곱하여 소수가 아닌 백분율을 얻어서 freq 열을 백분율로 읽기 쉽게 만듭니다.
getOption("scipen")
options("scipen"=10)
mtcars %>%
count(am, gear) %>%
mutate(freq = (n / sum(n)) * 100)
언급URL : https://stackoverflow.com/questions/24576515/relative-frequencies-proportions-with-dplyr
'programing' 카테고리의 다른 글
| 사용자 지정 구성 요소 | 초기화 전에 '스토어'에 액세스할 수 없습니다. (0) | 2023.06.13 |
|---|---|
| rs.last()가 전달 전용 결과 집합에 대해 잘못된 작업을 제공함: last (0) | 2023.06.13 |
| 업로드된 php 파일을 워드프레스로 실행하는 대신 일반 텍스트로 표시하는 방법은 무엇입니까? (0) | 2023.06.13 |
| ASP.NET 응용 프로그램이 로컬에서 실행 중인지 확인 (0) | 2023.06.13 |
| 엑셀에서 워드로 붙여넣은 차트의 파일 크기 줄이기 (0) | 2023.06.13 |