SQL에서 group by 연산처럼 수행을 도와주는 형태가 R에는 함수로 존재한다.
우선 group by 연산은 분리(그룹별) - 연산(적용) - 결합 의 매커니즘으로 구성되어 있다.
세 가지 정도 소개하려고 한다.
1. tapply
tapply(vector, # 연산대상
index, # 그룹핑 대상
function # 적용함수,
.....) # 함수의 추가 인수
위와 같은 문법으로 되어있다.
문법이 심플한 장점이 있으며, 비교적 단순한 문법이긴 하나 벡터로 리턴이 되는 것이 단점이다(data.frame 리턴 불가).
oracle에서는 group by 후 max(), count() 이렇게 여러 개 들어올 수 있는데 tapply는 하나의 연산 대상만 전달이 가능하다.
Line 2처럼 학년별 키의 평균을 구할 수 있으며, Line 4처럼 여러 개의 연산 대상 전달은 불가능하다.
2. aggregate
aggregate함수는 data.frame을 리턴한다.
여러 연산 대상, 여러 그룹핑 대상을 전달할 수 있다. 그러나 여러 연산 함수에 대해서는 전달이 불가능하다.
문법도 두 가지가 있는데, 첫 번째 문법은 다음과 같다.
1)
aggregate(x, # 연산대상
by, # 그룹핑 대상
FUN, # 연산 함수
...) # 연산 함수 추가 인수
2)
참고로, ~ 는 위치를 가지고 있는 공식으로, 통계에서는 종속변수~설명변수 라고 작성했을 때, 설명변수를 가지고 종속변수를 설명하라는 의미가 된다.
aggregate(x, # formmula(연산 대상 ~ 그룹핑 대상)
data, # 원본데이터(data.frame)
FUN, # 연산 함수
....., # 연산 함수 추가 인수
na.action = na.omit) # NA가 포함된 대상 처리 방식(기본은 제외), na.pass로 NA 리턴 가능
문법이 조금 복잡한 것 같아 바로 예시를 들어보겠다.
예1) 하나의 연산 대상, 하나의 그룹핑 대상
Line 5의 aggregate의 첫 번째 문법에서 두 번째 인수는 list 여야 한다(벡터 전달 시 에러). 그 이유는 이 자리에 여러 개를 전달해야하기 때문이다.
예2) 하나의 연산 대상, 두 개의 그룹핑 대상(학년별, 학과별)
여기서부터는 tapply 사용은 불가능하다. tapply는 그룹핑 대상이 하나만 오기 때문이다.
예3) 두 개의 연산 대상, 하나의 그룹핑 대상(연산 대상: 키와 몸무게 평균)
이 예시는 주의하여 봐야 한다.
우선 가장 중요한 Line 3번이다.
이 형식은 와이드 데이터의 그룹평 역할을 수월하게 해주는 형식으로 잘 기억해두자 ★ ★ ★
Line 5는 앞서 예시 2처럼 그룹핑 대상디 두 개 일 경우처럼 +로 두 대상을 연결하였다. 결과 값이 출력되어 오류가 없는 것처럼 느껴지나, 이 결과는 틀린 결과이다. 키와 몸무게를 더한 값을 그룹별 평균한 값이 된 것이다.
그러므로 연산 대상이 두 개가 나오는 경우 aggregate의 두 번째 문법을 사용하려면 cbind라는 함수로 묶어주어야 한다.
연습문제를 풀어보자.
1. professor.csv 데이터를 읽고
1) position별 급여의 평균을 구하여라
2) 직급별 학과별 급여와 보너스의 합을 구하여라
여기서는 tapply를 적용하지 못한다.
먼저 Line 4이다. aggregate의 첫 번째 문법으로, na.rm=T가 없으면 결측치는 NA로 나오고, na.rm = T로 하면 0으로 출력된다. 그러면서 모든 데이터인 16라인이 출력된다.
두 번째 문법을 사용하면 Line 7처럼 쓸 수 있는데, na.rm 옵션을 넣어도(Line 10) 10줄만 출력된다. 이 때 Line 13처럼 na.action 옵션을 넣어주어야지만 NA 값으로 출력되어 16줄이 모두 출력된다.
따라서 NA 출력이 NA 또는 0으로 출력될 수 있는 aggrecate의 첫 번째 문법을 잘 외워두도록 하자.
3. plyr::ddply
plyr패키지의 ddply 함수는 data.frame을 리턴한다.
여러 연산 대상 및 여러 그룹핑 대상을 전달하며, 여러 연산 함수도 전달이 가능하다.
transform기능도 포함하고 있다(이 기능은 다른 언어에서도 있는 기능이다, 내용은 아래에서).
정말 다양한 기능을 가지고 있으며 apply계열에서 발전된 함수이다.
그래서 __ply 의 형태를 가지고 있는 것이다.
apply 계열이 data frame 출력이 되지 않아 ddply가 나오게 된 것이다.
첫 실행 시 install을 하고 library로 불러온다.
install.packages('plyr')
library(plyr)
문법은 아래와 같다.
ddply(.data = , # 원본데이터(데이터 프레임)
.variables = , # 그룹핑 대상(복수 전달 가능)
.fun = , # 내부 함수()
...) # 연산대상과 연산함수 나열
ddply의 내부함수이다. (예시 같이)
1) summarise(summarize)() : 요약, 축소
- 가장 대표적
- 그룹별 요약(sql에서의 group by 연산 결과와 동일)
예1) emp에서 부서별 급여 평균(요약)
예2) emp에서 부서별 급여 평균, 최대값(요약)
2) transform() : 각각 행별로 그룹연산을 붙여넣는 행위
- 데이터 전체 출력(요약하지 않음)
- 각 행별 그룹 연산 결과 리턴
예1) emp에서 부서별 급여 평균(전체 출력)
예2) emp에서 부서별 급여 최대(전체 출력)
예3) emp에서 부서별 급여 최대, 로그 최대 급여(이전 컬럼 재사용)
에러가 난다.
이전 컬럼을 재사용 가능하게 하는 것이 mutate이다.
3) mutate()
- transform과 유사
- 이전 수행된 결과를 재사용할 수 있음
예) emp에서 부서별 급여 최대, 로그 최대 급여(이전 컬럼 재사용) (transform의 예3)
이렇게 되면 transform대신 mutate만 있다고 생각하고 mutate만 사용하면 되긴 하지만 모든 언어에서 transform이 있기 때문에 transform도 기억하여야 한다.
4. subset() ★
- 조건에 맞는 일부 데이터 선택
- sql의 group by 결과 후 having과 같은 기능
예) emp에서 부서별 최대 급여자 출력
연습문제
delivery.csv 파일을 읽고 시간대별 가장 인기있는 음식 업종을 시간대와 함께 출력하여라
위 결과는 ddply 결과이며, merge를 해서 푸는 방법도 있다(sol2).
하루 끝
R의 DB Connect 하는 방법도 알려주셨는데, 이건 다른 게시판으로 가서 작성할거라 여기서 마무리.
오늘은 복습 잘해둬야겠다. 이번주 너무 헷갈리는 게 많고 어려웠음.
'배우기 > 복습노트[R과 분석]' 카테고리의 다른 글
[실습문제] 2023. 12. 1.(금) (4문제) (0) | 2023.12.04 |
---|---|
[실습문제] 2023. 11. 30.(목) (2문제) (0) | 2023.12.04 |
[복습] R(programming language) 적용함수(sapply, lapply, mapply, apply) (2) + 하루끝(20231130) (0) | 2023.12.01 |
[실습문제] 2023. 11. 29.(수) (4문제) (0) | 2023.12.01 |
[복습] R(programming language) 적용함수(sapply) + 하루 끝(20231129) (0) | 2023.11.30 |