01. 데이터 형태 변환 (long data <-> wide data)
-01 데이터의 형태
-02 변환 함수
02. NA 처리
-01 NA 삭제
-02 NA 개수
-03 NA 치환
-04 NA로 치환
-05 연습문제
03. dplyr
-01 컬럼 선택
-02 연산하기
-03 행 선택
-04 정렬
-05 그룹연산
01. 데이터 형태 변환 (long data <-> wide data)
-01 데이터의 형태
1) long data
- 조인 유리
- DBMS에 적합한 데이터 형태
2) wide data
- 교차표 형태
- 행별 열별 집계결과 한눈에 파악 용이
- 조인, 그룹연산 불편
-02 변환 함수
1) reshape2::melt
wide -> long 변환
melt(data, # 원본데이터
id.vars, # 고정컬럼(제외한 모든 컬럼이 stact처리됨)
measure.vars, # stack 컬럼
variable.name = "variable", # 새로운 컬럼명(기존 컬럼들이 쌓이는 컬럼명)
...,
na.rm = FALSE, # NA 제거 여부
value.name = "value" # 새로운 컬럼명(기존 값(value)들이 쌓이는 컬럼명)
factorAsStrings = TRUE) # 문자컬럼 factor화
예)
df1 <- read.csv('melt_ex.csv')
melt(df1, id.vars = c('year','mon'))
> melt(df1, id.vars = c('year','mon'))
year mon variable value
1 2000 1 latte 400
2 2000 2 latte 401
3 2000 3 latte 402
4 2000 4 latte 403
5 2000 5 latte 404
6 2000 6 latte 405
7 2000 7 latte 406
8 2000 8 latte 407
9 2000 9 latte 408
10 2000 10 latte 409
melt(df1, id.vars = c('year','mon'), variable.name = 'name', value.name = 'qty')
> melt(df1, id.vars = c('year','mon'), variable.name = 'name', value.name = 'qty')
year mon name qty
1 2000 1 latte 400
2 2000 2 latte 401
3 2000 3 latte 402
4 2000 4 latte 403
5 2000 5 latte 404
6 2000 6 latte 405
7 2000 7 latte 406
8 2000 8 latte 407
9 2000 9 latte 408
10 2000 10 latte 409
melt(df1, measure.vars = c('latte', 'americano', 'mocha'), variable.name = 'name', value.name = 'qty')
> melt(df1, measure.vars = c('latte', 'americano', 'mocha'), variable.name = 'name', value.name = 'qty')
year mon name qty
1 2000 1 latte 400
2 2000 2 latte 401
3 2000 3 latte 402
4 2000 4 latte 403
5 2000 5 latte 404
6 2000 6 latte 405
7 2000 7 latte 406
8 2000 8 latte 407
9 2000 9 latte 408
10 2000 10 latte 409
# in sql)
select *
from df1
unpivot (qty for name in (latte, americano, mocha));
# 예) 2000-2013년_연령별실업율_40-49세.csv 데이터를 long data로 변환환
df1 <- read.csv('2000-2013년_연령별실업율_40-49세.csv', fileEncoding = 'cp949')
head(df1)
names(df1) <- str_remove_all(names(df1), 'X|년')
melt(df1, id.vars = '월', variable.name = '연도', value.name = '실업률')
## 문제풀이
df1 <- read.csv('2000-2013년_연령별실업율_40-49세.csv', fileEncoding = 'cp949')
df2 <- melt(df1, id.vars = '월', variable.name = '연도', value.name = '실업률')
df2$연도 <- str_remove_all(df2$연도, 'X|년')
df2
> df2
월 연도 실업률
1 1 2000 4.0
2 2 2000 4.5
3 3 2000 3.9
4 4 2000 3.6
5 5 2000 3.4
6 6 2000 3.3
7 7 2000 3.1
8 8 2000 3.2
9 9 2000 3.2
10 10 2000 3.1
11 11 2000 3.2
12 12 2000 3.5
13 1 2001 4.3
14 2 2001 4.5
15 3 2001 4.1
16 4 2001 3.3
17 5 2001 2.7
18 6 2001 2.4
19 7 2001 2.6
20 8 2001 2.9
# ** melt 옵션 정리 (na.rm)
test1 <- data.frame(year = c(2000,2001), A = c(90,80), B = c(NA, 100))
melt(test1, id.vars = 'year') # 2000년 B도 하나의 행으로 추가됨
melt(test1, id.vars = 'year', na.rm = T) # 2000년 B는 값이 없으므로 하나의 행으로 추가하지 않음
> melt(test1, id.vars = 'year')
year variable value
1 2000 A 90
2 2001 A 80
3 2000 B NA
4 2001 B 100
> melt(test1, id.vars = 'year', na.rm = T)
year variable value
1 2000 A 90
2 2001 A 80
4 2001 B 100
2) reshape2::dcast
long -> wide 변환
dcast(data, # 데이터
formula, # stack컬럼(행방향 배치) ~ unstack컬럼(열방향 배치)
fun.aggregate = NULL, # 요약함수(집계함수, default:length)
...,
margins = NULL, # 마진 출력 여부
subset = NULL, # 필터링 조건
fill = NULL, # NA 대신 표현할 값
drop = TRUE
value.var = guess_value(data)) # value 컬럼(생략시 자동으로 맨 마지막 컬럼 선택)
# 예) googleVis 패키지 내 Fruits 데이터를 교차표로 작성(과일별 연도별 판매량)
install.packages('googleVis')
library(googleVis)
dcast(Fruits, Fruit ~ Year, value.var = 'Sales')
> dcast(Fruits, Fruit ~ Year, value.var = 'Sales')
Fruit 2008 2009 2010
1 Apples 98 111 89
2 Bananas 85 94 81
3 Oranges 96 93 98
# 예) dcast_ex1.csv 파일을 읽고 아래 교차표 형태로 작성
# value.var 생략 시 맨 마지막 컬럼이 자동으로 선택됨
df1 <- read.csv('dcast_ex1.csv')
df1
dcast(df1, name ~ info, value.var = 'value')
> dcast(df1, name ~ info, value.var = 'value')
name price qty
1 latte 2200 100
2 mocha 2500 80
# 예) dcast_ex3.csv 파일을 읽고 아래 교차표 형태로 작성
df1 <- read.csv('dcast_ex3.csv', fileEncoding = 'cp949')
df1
# value column 자동선택 -> 수량
# Aggregation function 자동선택 -> length
dcast(df1, 년도 ~ 이름)
Using 수량 as value column: use value.var to override.
Aggregation function missing: defaulting to length 년도 latte mocha
1 2000 2 2
2 2001 2 2
dcast(df1, 년도 ~ 이름, value.var = '수량', fun.aggregate = sum)
> dcast(df1, 년도 ~ 이름, value.var = '수량', fun.aggregate = sum)
년도 latte mocha
1 2000 190 110
2 2001 190 110
# ** dcast 옵션 정리
test2 <- data.frame(id = c("A","A","B","B","C"),
name = c("latte","americano","latte","mocha","americano"),
qty = c(10, 5, 7, 3, 8))
> test2
id name qty
1 A latte 10
2 A americano 5
3 B latte 7
4 B mocha 3
5 C americano 8
# 1) fill
dcast(test2, id ~ name, value.var = 'qty')
dcast(test2, id ~ name, value.var = 'qty', fill = 0)
> dcast(test2, id ~ name, value.var = 'qty')
id americano latte mocha
1 A 5 10 NA
2 B NA 7 3
3 C 8 NA NA
> dcast(test2, id ~ name, value.var = 'qty', fill = 0)
id americano latte mocha
1 A 5 10 0
2 B 0 7 3
3 C 8 0 0
# 2) margins
dcast(test2, id ~ name, sum, value.var = 'qty')
dcast(test2, id ~ name, sum, value.var = 'qty', margins = T)
> dcast(test2, id ~ name, sum, value.var = 'qty')
id americano latte mocha
1 A 5 10 0
2 B 0 7 3
3 C 8 0 0
> dcast(test2, id ~ name, sum, value.var = 'qty', margins = T)
id americano latte mocha (all)
1 A 5 10 0 15
2 B 0 7 3 10
3 C 8 0 0 8
4 (all) 13 17 3 33
# 3) subset
dcast(test2, id ~ name, value.var = 'qty')
dcast(test2, id ~ name, value.var = 'qty', subset = .(id != 'C'))
> dcast(test2, id ~ name, value.var = 'qty')
id americano latte mocha
1 A 5 10 NA
2 B NA 7 3
3 C 8 NA NA
> dcast(test2, id ~ name, value.var = 'qty', subset = .(id != 'C'))
id americano latte mocha
1 A 5 10 NA
2 B NA 7 3
02. NA 처리
-01 NA 삭제
emp <- read.csv('emp.csv')
1) 특정 컬럼값이 NA인 행 삭제
emp[!is.na(emp$COMM),]
> emp[!is.na(emp$COMM),]
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
2 7499 ALLEN SALESMAN 7698 1981-02-20 0:00 1600 300 30
3 7521 WARD SALESMAN 7698 1982-02-22 0:00 1250 500 30
5 7654 MARTIN SALESMAN 7698 1981-09-28 0:00 1250 1400 30
10 7844 TURNER SALESMAN 7698 1981-09-08 0:00 1500 0 30
2) 모든 컬럼에 대해 NA가 하나라도 포함된 행 삭제
na.omit(emp)
> na.omit(emp)
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
2 7499 ALLEN SALESMAN 7698 1981-02-20 0:00 1600 300 30
3 7521 WARD SALESMAN 7698 1982-02-22 0:00 1250 500 30
5 7654 MARTIN SALESMAN 7698 1981-09-28 0:00 1250 1400 30
10 7844 TURNER SALESMAN 7698 1981-09-08 0:00 1500 0 30
-02 NA 개수
1) 특정 컬럼의 NA 수
sum(is.na(emp$COMM))
> sum(is.na(emp$COMM))
[1] 10
2) 각 컬럼마다의 NA 수
# 방법1)
f1 <- function(x) {
sum(is.na(x))
}
f1(emp$COMM)
f1(emp$EMPNO)
> f1(emp$COMM)
[1] 10
> f1(emp$EMPNO)
[1] 0
apply(emp, 2, f1)
> apply(emp, 2, f1)
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
0 0 0 1 0 0 10 0
# 방법2)
colSums(is.na(emp))
> colSums(is.na(emp))
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
0 0 0 1 0 0 10 0
3) 각 행마다의 NA 수
rowSums(is.na(emp))
> rowSums(is.na(emp))
[1] 1 0 0 1 0 1 1 1 2 0 1 1 1 1
# [ 연습문제 - NA 수 확인/행 제거 ]
bos <- read.csv('boston_na.csv')
bos
# 빈문자열 -> NA 치환
# 각 행마다 NA가 2회 이상 포함된 행 제거
# dis의 평균을 반올림하여 소수점 둘째자리까지 표현
is.na(bos)
bos[bos[,] == ""] <- NA
bos[bos[,] == "NA"] <- NA
bos
bos1 <- bos[!is.na(rowSums(is.na(bos)) >= 3),]
bos1
str(bos1)
bos1$dis <- as.numeric(bos1$dis, na.rm=T)
colMeans(bos1, na.rm = TRUE)
rowMeans(bos1, na.rm = TRUE)
round(mean(bos1$dis, na.rm = T), 2)
### 문제풀이 ###
# 1) 빈문자열 -> NA 치환
bos[bos == ""] <- NA
# 2) 각 행마다 NA가 2회 이상 포함된 행을 제거한 후 dis의 평균을 반올림하여 소수점 둘째자리까지 표현
bos2 <- bos[!(rowSums(is.na(bos)) >=2), ]
mean(bos2$dis, na.rm = T)
as.numeric(bos2$dis) # R에서는 수치변환 시 문자값들이 자동 NA로 변환됨
# * Python에서는 수치변환 시 문자값들이 변환되지 x
# 따라서 아래와 같이 문자가 포함되어있는지 확인하는 것이 좋다.
str_detect(bos2$dis, '^[[:punct:]]$')
bos2$dis <- as.numeric(bos2$dis)
round(mean(bos2$dis, na.rm = T), 2)
> round(mean(bos2$dis, na.rm = T), 2)
[1] 3.79
-03 NA 치환
1) stringr::str_replace_na
문자만 사용 가능하다.
str_replace_na(c('a','b',NA), 'a')
> str_replace_na(c('a','b',NA), 'a')
[1] "a" "b" "a
str_replace_na(emp$COMM, 0) # 숫자상수로의 치환 불가
> str_replace_na(emp$COMM, 0)
Error in `str_replace_na()`:
! `replacement` must be a single string, not the number 0.
Run `rlang::last_trace()` to see where the error occurred.
2) dplyr::coalesce
숫자, 문자 모두 사용 가능하다.
coalesce(emp$COMM, 0)
> coalesce(emp$COMM, 0)
[1] 0 300 500 0 1400 0 0 0 0 0 0 0 0 0
v1 <- c(1,2,3,NA,NA)
v2 <- c(1,2,3,4,NA)
coalesce(v1,v2)
NA였을 때 같은 위치에 있는 NA가 아닌 값으로 치환을 진행한다.
v1, v2 모두 NA인 경우 NA를 리턴한다.
> coalesce(v1,v2)
[1] 1 2 3 4 NA
coalesce(c('a',NA), 'a')
> coalesce(c('a',NA), 'a')
[1] "a" "a"
3) tidyr::replace_na
여러 컬럼의 NA를 동시에 치환 가능하다.
install.packages('tidyr')
library(tidyr)
replace_na(emp$COMM, 0)
> replace_na(emp$COMM, 0)
[1] 0 300 500 0 1400 0 0 0 0 0 0 0 0 0
df_na <- data.frame(A=c(1,2,3,NA), B=c('a','b',NA,'d'))
replace_na(df_na, list(A=0, B='a'))
> replace_na(df_na, list(A=0, B='a'))
A B
1 1 a
2 2 b
3 3 a
4 0 d
-04 NA로 치환
# in sql) nullif(COMM, 500)
dplyr::na_if(emp$COMM, 1400)
> na_if(emp$COMM, 1400)
[1] NA 300 500 NA NA NA NA NA NA 0 NA NA NA NA
-05 연습문제
cancer <- read.csv('cancer_test.csv')
str(cancer)
colSums(is.na(cancer))
cancer$symmetry_mean[str_detect(cancer$symmetry_mean, '^[[:punct:]]$')]
# 1) radius_mean 의 결측치를 제외한 데이터의 평균으로 수정
cancermean <- mean(cancer$radius_mean, na.rm=T)
cancer$radius_mean[is.na(cancer$radius_mean)] <- cancermean
### 문제풀이 ###
vmean1 <- mean(cancer$radius_mean, na.rm=T)
coalesce(cancer$radius_mean, vmean1)
> coalesce(cancer$radius_mean, vmean1)
[1] 17.99000 20.57000 19.69000 11.42000 20.29000 12.45000 18.25000 13.71000 13.00000 12.46000
[11] 16.02000 15.78000 19.17000 15.85000 13.73000 14.54000 14.68000 16.13000 19.81000 13.54000
[21] 13.08000 9.50400 15.34000 21.16000 16.65000 17.14000 14.58000 18.61000 15.30000 17.57000
# 2) texture_mean의 결측치를 제외한 데이터의 상위 10%의 평균값으로 수정
cancer$texture_mean
top <- nrow(cancer) * 0.1
cancer$texture_mean[rank(cancer$texture_mean) <= top]
cancermean2 <- mean(cancer$texture_mean[rank(cancer$texture_mean) <= top], na.rm=T)
cancer$texture_mean[is.na(cancer$texture_mean)] <- cancermean2
### 문제풀이 ###
nrow <- trunc((nrow(cancer) - sum(is.na(cancer$texture_mean))) * 0.1)
vmean2 <- mean(sort(cancer$texture_mean, decreasing = T)[1:nrow])
coalesce(cancer$texture_mean, vmean2)
> coalesce(cancer$texture_mean, vmean2)
[1] 10.38000 17.77000 21.25000 20.38000 14.34000 15.70000 19.98000 20.83000 21.82000 24.04000
[11] 23.24000 17.89000 24.80000 23.95000 22.61000 27.54000 20.13000 20.68000 22.15000 14.36000
[21] 15.71000 12.44000 14.26000 23.04000 21.38000 16.40000 21.53000 20.25000 25.27000 15.05000
03. dplyr
- sql 처럼 구조적 문장 작성 가능
- 윈도우함수(lag, lead, densc_rank 등) 제공, 다양한 연산자(between)
%>% : ctrl + shift + m
- 내부함수
1) select : 컬럼 선택
2) filter : 행 선택
3) mutate : 연산
4) group_by : 그룹대상 전달
5) summarise : 그룹연산
6) arrange : 정렬
-01 컬럼 선택
emp %>%
select(EMPNO, ENAME) # 일부컬럼 선택
emp %>%
select(-EMPNO) # 일부컬럼 제외
emp %>%
select('JOB':'SAL') # 문자컬럼 연속 추출 가능
emp %>%
select(SAL, everything()) # 일부컬럼과 전체컬럼을 동시 출력 가능
> emp %>%
+ select(EMPNO, ENAME) # 일부컬럼 선택
EMPNO ENAME
1 7369 SMITH
2 7499 ALLEN
3 7521 WARD
4 7566 JONES
5 7654 MARTIN
6 7698 BLAKE
7 7782 CLARK
8 7788 SCOTT
9 7839 KING
10 7844 TURNER
11 7876 ADAMS
12 7900 JAMES
13 7902 FORD
14 7934 MILLER
emp %>%
select(-EMPNO) # 일부컬럼 제외
> emp %>%
+ select(-EMPNO) # 일부컬럼 제외
ENAME JOB MGR HIREDATE SAL COMM DEPTNO
1 SMITH CLERK 7902 1980-12-17 0:00 800 NA 20
2 ALLEN SALESMAN 7698 1981-02-20 0:00 1600 300 30
3 WARD SALESMAN 7698 1982-02-22 0:00 1250 500 30
4 JONES MANAGER 7839 1981-04-02 0:00 2975 NA 20
5 MARTIN SALESMAN 7698 1981-09-28 0:00 1250 1400 30
6 BLAKE MANAGER 7839 1981-05-01 0:00 2850 NA 30
7 CLARK MANAGER 7839 1981-06-09 0:00 2450 NA 10
8 SCOTT ANALYST 7566 1987-04-17 0:00 3000 NA 20
9 KING PRESIDENT NA 1981-11-17 0:00 5000 NA 10
10 TURNER SALESMAN 7698 1981-09-08 0:00 1500 0 30
11 ADAMS CLERK 7788 1987-05-23 0:00 1100 NA 20
12 JAMES CLERK 7698 1981-12-03 0:00 950 NA 30
13 FORD ANALYST 7566 1981-12-03 0:00 3000 NA 20
14 MILLER CLERK 7782 1982-01-23 0:00 1300 NA 10
emp %>%
select('JOB':'SAL') # 문자컬럼 연속 추출 가능
> emp %>%
+ select('JOB':'SAL') # 문자컬럼 연속 추출 가능
JOB MGR HIREDATE SAL
1 CLERK 7902 1980-12-17 0:00 800
2 SALESMAN 7698 1981-02-20 0:00 1600
3 SALESMAN 7698 1982-02-22 0:00 1250
4 MANAGER 7839 1981-04-02 0:00 2975
5 SALESMAN 7698 1981-09-28 0:00 1250
6 MANAGER 7839 1981-05-01 0:00 2850
7 MANAGER 7839 1981-06-09 0:00 2450
8 ANALYST 7566 1987-04-17 0:00 3000
9 PRESIDENT NA 1981-11-17 0:00 5000
10 SALESMAN 7698 1981-09-08 0:00 1500
11 CLERK 7788 1987-05-23 0:00 1100
12 CLERK 7698 1981-12-03 0:00 950
13 ANALYST 7566 1981-12-03 0:00 3000
14 CLERK 7782 1982-01-23 0:00 1300
emp %>%
select(SAL, everything()) # 일부컬럼과 전체컬럼을 동시 출력 가능
> emp %>%
+ select(SAL, everything()) # 일부컬럼과 전체컬럼을 동시 출력 가능
SAL EMPNO ENAME JOB MGR HIREDATE COMM DEPTNO
1 800 7369 SMITH CLERK 7902 1980-12-17 0:00 NA 20
2 1600 7499 ALLEN SALESMAN 7698 1981-02-20 0:00 300 30
3 1250 7521 WARD SALESMAN 7698 1982-02-22 0:00 500 30
4 2975 7566 JONES MANAGER 7839 1981-04-02 0:00 NA 20
5 1250 7654 MARTIN SALESMAN 7698 1981-09-28 0:00 1400 30
6 2850 7698 BLAKE MANAGER 7839 1981-05-01 0:00 NA 30
7 2450 7782 CLARK MANAGER 7839 1981-06-09 0:00 NA 10
8 3000 7788 SCOTT ANALYST 7566 1987-04-17 0:00 NA 20
9 5000 7839 KING PRESIDENT NA 1981-11-17 0:00 NA 10
10 1500 7844 TURNER SALESMAN 7698 1981-09-08 0:00 0 30
11 1100 7876 ADAMS CLERK 7788 1987-05-23 0:00 NA 20
12 950 7900 JAMES CLERK 7698 1981-12-03 0:00 NA 30
13 3000 7902 FORD ANALYST 7566 1981-12-03 0:00 NA 20
14 1300 7934 MILLER CLERK 7782 1982-01-23 0:00 NA 10
-02 연산하기
emp %>%
select(EMPNO, ENAME, SAL, SAL*1.1) # select 내 연산식 전달 불가
> emp %>%
+ select(EMPNO, ENAME, SAL, SAL*1.1) # select 내 연산식 전달 불가
Error in `select()`:
! Can't use arithmetic operator `*` in selection context.
Run `rlang::last_trace()` to see where the error occurred.
emp %>%
mutate(NEW_SAL = SAL*1.1)
> emp %>%
+ mutate(NEW_SAL = SAL*1.1)
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO NEW_SAL
1 7369 SMITH CLERK 7902 1980-12-17 0:00 800 NA 20 880.0
2 7499 ALLEN SALESMAN 7698 1981-02-20 0:00 1600 300 30 1760.0
3 7521 WARD SALESMAN 7698 1982-02-22 0:00 1250 500 30 1375.0
4 7566 JONES MANAGER 7839 1981-04-02 0:00 2975 NA 20 3272.5
5 7654 MARTIN SALESMAN 7698 1981-09-28 0:00 1250 1400 30 1375.0
6 7698 BLAKE MANAGER 7839 1981-05-01 0:00 2850 NA 30 3135.0
7 7782 CLARK MANAGER 7839 1981-06-09 0:00 2450 NA 10 2695.0
8 7788 SCOTT ANALYST 7566 1987-04-17 0:00 3000 NA 20 3300.0
9 7839 KING PRESIDENT NA 1981-11-17 0:00 5000 NA 10 5500.0
10 7844 TURNER SALESMAN 7698 1981-09-08 0:00 1500 0 30 1650.0
11 7876 ADAMS CLERK 7788 1987-05-23 0:00 1100 NA 20 1210.0
12 7900 JAMES CLERK 7698 1981-12-03 0:00 950 NA 30 1045.0
13 7902 FORD ANALYST 7566 1981-12-03 0:00 3000 NA 20 3300.0
14 7934 MILLER CLERK 7782 1982-01-23 0:00 1300 NA 10 1430.0
emp %>%
select(EMPNO, ENAME) %>%
mutate(NEW_SAL = SAL*1.1) # error(순차적으로 전달되므로 sal의 결과가 존재하지 않음)
> emp %>%
+ select(EMPNO, ENAME) %>%
+ mutate(NEW_SAL = SAL*1.1) # error(순차적으로 전달되므로 sal의 결과가 존재하지 않음)
Error in `mutate()`:
ℹ In argument: `NEW_SAL = SAL * 1.1`.
Caused by error:
! 객체 'SAL'를 찾을 수 없습니다
Run `rlang::last_trace()` to see where the error occurred.
-03 행 선택
emp %>%
mutate(NEW_SAL = SAL*1.1) %>%
select(EMPNO, ENAME, SAL, NEW_SAL) %>%
dplyr::filter(NEW_SAL >= 3000)
# 간혹 filter 실행 시 stats 패키지의 filter가 호출되는 경우가 있으므로
# 패키지명을 기재하여 dplyr::filter로 전달을 권고!
> emp %>%
+ mutate(NEW_SAL = SAL*1.1) %>%
+ select(EMPNO, ENAME, SAL, NEW_SAL) %>%
+ dplyr::filter(NEW_SAL >= 3000)
EMPNO ENAME SAL NEW_SAL
1 7566 JONES 2975 3272.5
2 7698 BLAKE 2850 3135.0
3 7788 SCOTT 3000 3300.0
4 7839 KING 5000 5500.0
5 7902 FORD 3000 3300.0
-04 정렬
emp %>%
mutate(NEW_SAL = SAL*1.1) %>%
select(EMPNO, ENAME, SAL, NEW_SAL) %>%
dplyr::filter(NEW_SAL >= 3000) %>%
arrange(-NEW_SAL)
> emp %>%
+ mutate(NEW_SAL = SAL*1.1) %>%
+ select(EMPNO, ENAME, SAL, NEW_SAL) %>%
+ dplyr::filter(NEW_SAL >= 3000) %>%
+ arrange(-NEW_SAL)
EMPNO ENAME SAL NEW_SAL
1 7839 KING 5000 5500.0
2 7788 SCOTT 3000 3300.0
3 7902 FORD 3000 3300.0
4 7566 JONES 2975 3272.5
5 7698 BLAKE 2850 3135.0
-05 그룹연산
emp %>%
group_by(DEPTNO) %>%
summarise(SUMSAL = sum(SAL), MEANSAL = mean(SAL))
> emp %>%
+ group_by(DEPTNO) %>%
+ summarise(SUMSAL = sum(SAL), MEANSAL = mean(SAL))
# A tibble: 3 × 3
DEPTNO SUMSAL MEANSAL
<int> <int> <dbl>
1 10 8750 2917.
2 20 10875 2175
3 30 9400 1567.
# [ 연습문제 ]
std <- read.csv('student.csv', fileEncoding = 'cp949')
std
# student.csv 파일을 불러온 뒤 1,2학년 학생의 이름, 학년, 성별, 키 출력
# 단, 성별과 키 순서대로 정렬(키는 높은순)
# ifelse
std %>%
mutate(성별 = ifelse(substr(JUMIN, 7, 7)==1, '남자', '여자')) %>%
select(NAME, GRADE, 성별, HEIGHT) %>%
dplyr::filter(GRADE %in% c("1", "2")) %>%
arrange(성별, -HEIGHT)
#### 문제풀이
std %>%
filter(between(GRADE, 1,2)) %>%
mutate(성별 = ifelse(str_sub(JUMIN, 7, 7) == '1', '남자', '여자')) %>%
select(NAME, GRADE, 성별, HEIGHT) %>%
arrange(성별, -HEIGHT)
> std %>%
+ filter(between(GRADE, 1,2)) %>%
+ mutate(성별 = ifelse(str_sub(JUMIN, 7, 7) == '1', '남자', '여자')) %>%
+ select(NAME, GRADE, 성별, HEIGHT) %>%
+ arrange(성별, -HEIGHT)
NAME GRADE 성별 HEIGHT
1 노정호 2 남자 184
2 일지매 2 남자 182
3 김주현 1 남자 179
4 안광훈 2 남자 175
5 안은수 1 남자 175
6 인영민 1 남자 173
7 김진욱 2 남자 171
8 김문호 2 남자 166
9 허우 1 여자 163
10 이윤나 1 여자 162'아이티윌_데이터 분석 55기 > 강의내용 필기_통계 및 분석' 카테고리의 다른 글
| #9 9일차_기본 시각화 : barplot, 이상치 탐색, 히스토그램, 커널밀도, 파이차트 (0) | 2026.04.10 |
|---|---|
| #8 8일차_dplyr, 시각화 (0) | 2026.04.09 |
| #6 6일차 : 외부파일 입출력, DB Connection, 기타 기능 (0) | 2026.04.07 |
| #5 5일차_적용함수, 자료구조 (0) | 2026.04.03 |
| #4 4일차_집합연산자, 조건문, 반복문, 사용자 정의 함수, 적용함수 (0) | 2026.04.02 |