아이티윌_데이터 분석 55기/강의내용 필기_통계 및 분석

#7 7일차_데이터 형태 변환, NA 처리

ecosso 2026. 4. 8. 16:23

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