[R] 9. 기술통계분석
반응형
0. 예시로 쓰일 데이터 예제
set.seed(2021)
# 임의로 데이터를 생성한다. (100명의 유저가 특정 곡을 스트리밍한 이력)
temp <- tibble(
user_id = c(10000:10149),
user_age = sample(x = round(runif(n = 50, min = 18, max = 50), 0), size = 150, replace = TRUE),
user_gender = sample(x = c("남성", "여성"), size = 150, prob = c(0.5, 0.5), replace = TRUE),
song_id = sample(x = letters[1:15], size = 150, replace = TRUE),
streaming_count = rpois(n = 150, lambda = 20),
download_count = rpois(n = 150, lambda = 5)
) %>%
mutate(
song_class_flag = case_when(
song_id %in% c("d", "e", "f") ~ "인기곡",
TRUE ~ "비인기곡"
)
)
temp
## # A tibble: 150 x 7
## user_id user_age user_gender song_id streaming_count download_count
## <int> <dbl> <chr> <chr> <int> <int>
## 1 10000 44 여성 e 20 6
## 2 10001 47 남성 f 21 6
## 3 10002 49 남성 k 14 3
## 4 10003 44 남성 j 8 4
## 5 10004 26 여성 f 20 5
## 6 10005 44 여성 j 17 2
## 7 10006 20 여성 j 24 3
## 8 10007 27 남성 l 24 1
## 9 10008 34 여성 f 20 5
## 10 10009 26 남성 d 27 6
## # … with 140 more rows, and 1 more variable: song_class_flag <chr>
1. 들어가며..
- 우선 기술통계치를 계산하기 위한 함수들로는
count()
함수와summarise_*()
함수 등을 언급할 수 있습니다.summarise()
: 개별 함수에만 적용되는 함수summarise_if()
: 특정 조건을 만족하는 변수에만 적용되는 함수summarise_at()
: 지정된 변수명이나 위치에 있는 변수에만 적용되는 함수summarise_all()
: 모든 변수들에 적용되는 함수
- 이와 더불어 기술통계분석 결과를 시각화할 수 있는 라이브러리로는 대표적으로
ggplot2
가 있습니다.
(tidyverse
의 부속 라이브러리에는ggplot2
가 내포되어 있습니다) - 시각화도 같이 설명하면 좋겠지만,
ggplot2
에 대한 설명은 따로 포스팅하도록 하겠습니다.
2. 단순 빈도분석
- 단순히 로그의 수를 세기에는
count()
함수를 사용할 수 있습니다.
# 단순히 count() 함수만 사용하여 song_id 카운팅
temp %>%
count(song_id)
## # A tibble: 15 x 2
## song_id n
## <chr> <int>
## 1 a 9
## 2 b 9
## 3 c 8
## 4 d 12
## 5 e 5
## 6 f 14
## 7 g 8
## 8 h 6
## 9 i 15
## 10 j 13
## 11 k 8
## 12 l 15
## 13 m 9
## 14 n 9
## 15 o 10
# group_by() + summarise() + n() 사용
temp %>%
group_by(song_id) %>%
summarise(n = n())
## # A tibble: 15 x 2
## song_id n
## <chr> <int>
## 1 a 9
## 2 b 9
## 3 c 8
## 4 d 12
## 5 e 5
## 6 f 14
## 7 g 8
## 8 h 6
## 9 i 15
## 10 j 13
## 11 k 8
## 12 l 15
## 13 m 9
## 14 n 9
## 15 o 10
- 때로는 유니크 집계값이 필요할 수도 있습니다.
- 유니크 집계가 필요한 경우는
summarise()
함수 안에서n_distinct()
함수를 사용할 수 있습니다.
temp %>%
group_by(song_id) %>%
summarise(user_count = n_distinct(user_id))
## # A tibble: 15 x 2
## song_id user_count
## <chr> <int>
## 1 a 9
## 2 b 9
## 3 c 8
## 4 d 12
## 5 e 5
## 6 f 14
## 7 g 8
## 8 h 6
## 9 i 15
## 10 j 13
## 11 k 8
## 12 l 15
## 13 m 9
## 14 n 9
## 15 o 10
- 이번에는 유저의 연령대를 10단위로 범주화하여 연령대별/성별 유저 수를 계산해보겠습니다.
# count() 함수만 사용
temp %>%
mutate(
user_age_category = cut_width(user_age, width = 10),
user_gender
) %>%
count(user_age_category, user_gender)
## # A tibble: 8 x 3
## user_age_category user_gender n
## <fct> <chr> <int>
## 1 [15,25] 남성 12
## 2 [15,25] 여성 16
## 3 (25,35] 남성 17
## 4 (25,35] 여성 14
## 5 (35,45] 남성 21
## 6 (35,45] 여성 23
## 7 (45,55] 남성 28
## 8 (45,55] 여성 19
# group_by() + summarise() + n_distinct() 사용
temp %>%
group_by(
user_age_category = cut_width(user_age, width = 10),
user_gender
) %>%
summarise(user_count = n_distinct(user_id)) %>%
ungroup()
## # A tibble: 8 x 3
## user_age_category user_gender user_count
## <fct> <chr> <int>
## 1 [15,25] 남성 12
## 2 [15,25] 여성 16
## 3 (25,35] 남성 17
## 4 (25,35] 여성 14
## 5 (35,45] 남성 21
## 6 (35,45] 여성 23
## 7 (45,55] 남성 28
## 8 (45,55] 여성 19
- 이렇게 집계한 데이터는
spread()
함수를 사용하여 교차표의 형태로도 만들 수 있습니다.
# 위 결과에 spread() 함수를 사용하여 교차분석표를 생성
temp %>%
group_by(
user_age_category = cut_width(user_age, width = 10),
user_gender
) %>%
summarise(user_count = n_distinct(user_id)) %>%
ungroup() %>%
spread(key = "user_age_category", value = "user_count")
## `summarise()` has grouped output by 'user_age_category'. You can override using the `.groups` argument.
## # A tibble: 2 x 5
## user_gender `[15,25]` `(25,35]` `(35,45]` `(45,55]`
## <chr> <int> <int> <int> <int>
## 1 남성 12 17 21 28
## 2 여성 16 14 23 19
mutate_if
함수를 적용하여 특정 조건을 만족하는 변수에 함수를 씌울 수도 있습니다.
temp %>%
group_by(
user_age_category = cut_width(user_age, width = 10),
user_gender
) %>%
summarise(user_count = n_distinct(user_id)) %>%
ungroup() %>%
mutate_if(
is.integer, # (1 )정수형(integer) 변수들을 대상으로
funs((./sum(.))*100) # (2) 빈도를 백분율로 표시
) %>%
spread(key = "user_age_category", value = "user_count")
## # A tibble: 2 x 5
## user_gender `[15,25]` `(25,35]` `(35,45]` `(45,55]`
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 남성 8 11.3 14 18.7
## 2 여성 10.7 9.33 15.3 12.7
3. 기술통계량 계산
- 한 개의 연속형 변수에 대해서 기술통계량을 구해볼 수 있습니다.
- 아래 예시에 적용된 사례뿐만 아니라 베이스로 계산할 수 있는 계산들 대부분 다 적용이 가능합니다. (상관계수, 분위수 등)
# 평균 스트리밍 횟수 구하기
temp %>%
summarise(avg_streaming_count = mean(streaming_count, na.rm = TRUE))
## # A tibble: 1 x 1
## avg_streaming_count
## <dbl>
## 1 19.9
# 스트리밍 횟수 중앙값 구하기
temp %>%
summarise(med_streaming_count = median(streaming_count, na.rm = TRUE))
## # A tibble: 1 x 1
## med_streaming_count
## <dbl>
## 1 20
# 스트리밍 횟수 최소값 구하기
temp %>%
summarise(min_streaming_count = min(streaming_count, na.rm = TRUE))
## # A tibble: 1 x 1
## min_streaming_count
## <int>
## 1 6
# 스트리밍 횟수 최대값 구하기
temp %>%
summarise(max_streaming_count = max(streaming_count, na.rm = TRUE))
## # A tibble: 1 x 1
## max_streaming_count
## <int>
## 1 37
# 스트리밍 횟수 표준편차 구하기
temp %>%
summarise(std_streaming_count = sd(streaming_count, na.rm = TRUE))
## # A tibble: 1 x 1
## std_streaming_count
## <dbl>
## 1 5.14
- 여러 번수들의 통계량 또한 구할 수 있습니다.
- 이 떄에는
summarise_at()
함수를 사용하며vars()
파라미터에는 변수명 또는 변수의 위치(몇번째)값을 입력합니다.
# 유저의 연령대, 스트리밍 횟수, 다운로드 횟수의 평균값
temp %>%
summarise_at(
vars("user_age", "streaming_count", "download_count"),
funs(mean(., na.rm = TRUE))
)
## # A tibble: 1 x 3
## user_age streaming_count download_count
## <dbl> <dbl> <dbl>
## 1 37.3 19.9 5.22
temp %>%
summarise_at(
vars(c(2, 5, 6)),
funs(mean(., na.rm = TRUE))
)
## # A tibble: 1 x 3
## user_age streaming_count download_count
## <dbl> <dbl> <dbl>
## 1 37.3 19.9 5.22
- 위 결과를 그룹별로도 확인해볼 수 있습니다.
- 이 때에는
group_by()
함수를 통해 그룹화시킬 변수를 정의해줍니다.
# 남성/여성 유저별 유저의 연령대, 스트리밍 횟수, 다운로드 횟수의 평균값
temp %>%
group_by(user_gender) %>%
summarise_at(
vars("user_age", "streaming_count", "download_count"),
funs(mean(., na.rm = TRUE))
)
## # A tibble: 2 x 4
## user_gender user_age streaming_count download_count
## <chr> <dbl> <dbl> <dbl>
## 1 남성 37.9 19.8 5.26
## 2 여성 36.8 20.1 5.18
- 커스텀 함수를 정의하여 동일하게 적용할 수 있습니다. 아래는 예시입니다.
# 99% 신뢰구간을 구하는 함수를 정의
cal_ci <- function(vals){
avg = mean(vals, na.rm = TRUE)
std = sd(vals, na.rm = TRUE)
n = length(vals)
lower = round(avg - 2.58*std/sqrt(n), 2)
upper = round(avg + 2.58*std/sqrt(n), 2)
result = paste0(
round(avg, 2), " (", lower, ", ", upper, ")"
)
result
}
# 위에서 정의한 커스텀 함수를 summarise_at() 함수에 적용
temp %>%
group_by(user_gender) %>%
summarise_at(
vars("streaming_count", "download_count"),
funs(cal_ci)
)
## # A tibble: 2 x 3
## user_gender streaming_count download_count
## <chr> <chr> <chr>
## 1 남성 19.77 (18.45, 21.09) 5.26 (4.5, 6.01)
## 2 여성 20.14 (18.39, 21.89) 5.18 (4.3, 6.06)
반응형
'tidyverse' 카테고리의 다른 글
[R] 11. t-Test (0) | 2021.07.13 |
---|---|
[R] 10. 피어슨 상관계수(Pearson's Corrleation) (0) | 2021.07.06 |
[R] 8. 데이터 합치기 (join) (0) | 2021.07.05 |
[R] 7. 데이터 형태 변환 (0) | 2021.07.05 |
[R] 6. 날짜 및 시간 변수 (lubridate) (3) | 2021.07.05 |
TAGS.