R로 데이터 다루기

R에서 dplyr을 이용해 데이터를 추출, 가공하는 방법을 알아봅니다


수강중

12. dplyr 함수들을 조합한 실전 데이터 다루기 1 - 1

dplyr 불러오기

library(dplyr)
Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

기후데이터를 불러온다.

climates <- read.csv('seoul_climate.csv', stringsAsFactors = F,
                     fileEncoding = 'UTF-8')

변수 이름을 변경한다.

colnames(climates) <- c('city', 'district', 'ym', 'lon', 'lat', 'rainfall')

변수 확인

task 1

6월에서 9월까지, 월별 평균 강수량을 구하세요.

6월에서 9월까지

nchar(climates$ym) %>% table을 통해 연월 변수가 모두 6자리인지 확인을 한다.

nchar(climates$ym) %>% table
.
  6 
600 

task 1 코드 정리

climates %>%
    mutate(m = substr(ym, 5,6)) %>%
    filter(m >= '06' & m <= '09') %>%
    group_by(m) %>%
    summarise(mean.rainfall = mean(rainfall))
  m  mean.rainfall
1 06 NA           
2 07 NA           
3 08 NA           
4 09 NA           

task 1 코드 문제점

  • ym의 데이터를 확인하면 201401로 월에 해당하는 데이터는 01 2자리이다. filter에서 6월 이상 9월 이하 부분을 06, 09로 바꿔야 한다.
  • m은 숫자가 아닌 문자열 이기 때문에 filter에서 6월 이상 9월 이하 부분을 문자열로 변경해줘야한다. 다시 실행해보면 데이터가 잘 추출된 것을 알 수 있다.
climates %>%
    mutate(m = substr(ym, 5,6)) %>%
    filter(m >= '06' & m <= '09') %>%
    group_by(m) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm=T))
  m  mean.rainfall
1 06 103.00000    
2 07  76.39024    
3 08  94.94286    
4 09  71.67568    

task 2

6월에서 9월까지, 월별 평균 강수량을 구하세요. 내림차순 정렬을 하세요.

task 1의 코드를 내림차순 정렬로 해주면 된다. 그리고 chain을 하나 더 넣고 arrange(desc()) 로 내림차순으로 정렬을 한다.

climates %>%
    mutate(m = substr(ym, 5,6)) %>%
    filter(m >= '06' & m <= '09') %>%
    group_by(m) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm=T)) %>%
    arrange(desc(mean.rainfall))
  m  mean.rainfall
1 06 103.00000    
2 08  94.94286    
3 07  76.39024    
4 09  71.67568    

task 3

6월에서 9월까지, 구별 & 월별 평균 강수량을 구하세요. 전체에서 내림차순 정렬을 하세요.

ungroup

ungroup으로 정렬을 푼후, 다시 arrange를 실행해 전체의 내림차순을 적용시킨다.

climates %>%
    mutate(m = substr(ym, 5,6)) %>%
    filter(m >= '06' & m <= '09') %>%
    group_by(district, m) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm=T)) %>%
    ungroup %>%
    arrange(desc(mean.rainfall))
    district m   mean.rainfall
1   노원구   06  253.0        
2   동작구   08  220.0        
3   송파구   06  212.0        
4   서대문구 08  210.0        

task 4 풀이1

2014년 12월에서 가장 비가 많이 온 날과 2015년 9월에서 가장 비가 많이 온 지역을 출력해보세요.

filter로 12월을 뽑는다.

desc으로 내림차순 정렬한다.

slice로 첫 번째 데이터, 가장 강수량이 많았던 데이터를 뽑는다.

climates %>%
    filter(ym == '201412') %>%
    arrange(desc(rainfall)) %>%
    slice(1)
  city       district ym     lon      lat      rainfall
1 서울특별시 관악구   201412 37.46738 126.9453 276     

task 4 풀이2

filter까지는 이전과 같다. group_by에 연월을 넣어주고, summarise에서 max 값을 뽑아.낸다.

climates %>%
    filter(ym == '201412') %>%
    group_by(ym) %>%
    summarise(max.rainfall = max(rainfall, na.rm = T))
  ym     max.rainfall
1 201412 276         

최대치를 뽑았으니 해당 지역을 뽑는다. 위에서 뽑은 결과(최대 강수량)을 filter에 넘겨줘서 지역을 찾으면 된다.

climates %>% filter(rainfall == 276)
  city       district ym     lon      lat      rainfall
1 서울특별시 관악구   201412 37.46738 126.9453 276     

task 4

ym == '201509'로 2015년 9월에서 가장 비가 많이 온 지역을 출력한다.select(district)`로 지역만 뽑아낼 수 있다.

climates %>%
    filter(ym == '201509') %>%
    arrange(desc(rainfall)) %>%
    slice(1) %>%
    select(district)
  district
1 금천구  

task 5

구별 평균 강수량을 구하되, 내림차순으로 순위를 매기시오.

rank

rank 라는 것은 순서를 매기는 것이다. 오름차순으로 순위를 매긴다.

rank(c(30, 20, 10, 40, 50))
[1] 3 2 1 4 5

동률

동률이 있으면 그 순위들의 평균이 되는데, 아래의 결과처럼 1.5, 1.5의 결과가 나온다.

rank(c(30, 20, 10, 10, 50))
[1] 4.0 3.0 1.5 1.5 5.0

rank 옵션

ties.method

어떤 값을 쓰냐는 개인에 따라 다르다.

여러 옵션중 ties.methodaverage를 넘겨주면 이전과 같은 결과로 나오게 된다.

rank(c(30, 20, 10, 10, 50), ties.method = 'average')
[1] 4.0 3.0 1.5 1.5 5.0

ties.methodmin으로 변경하면 아래의 결과는 2등은 사라지고 공동 1등이 나온다.

rank(c(30, 20, 10, 10, 50), ties.method = 'min')
[1] 4 3 1 1 5

ties.methodfirst으로 변경하면 동율에 대해서 순서대로 랭킹을 준다.

rank(c(30, 20, 10, 10, 50), ties.method = 'first')
[1] 4 3 1 2 5

내림차순 순위 정렬하기

전체에 -1 을 곱해주면 순서가 뒤집힌다. 데이터에 -1을 곱해주고, 내림차순으로 정렬해주면 된다.

rank(-1*c(30, 20, 10, 10, 50), ties.method = 'min')
[1] 2 3 4 4 1

group by(distric)summarise(mean)으로 구별 강수량의 평균을 구한다.

climates %>%
    group_by(district) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm = T))
   district mean.rainfall
1  강남구    81.78947    
2  강동구    88.31579    
3  강북구    91.83333    
4  강서구   118.00000    

ties.methodmin으로 옵션을 주어 랭킹을 한뒤, 변수에 -를 붙어 내림차순 정렬을 한다. 이미 내림차순 정렬이 되엉있기 때문에 arrange할 때 desc을 안해도 된다.

task 6

5번 결과에서 송파구, 강남구, 중랑구만 선택하여, 다시 평균 강수량의 내림차순으로 재정렬하세요.

filter(%in%)을 사용하여 원하는 구를 선택한다.

climates %>%
    group_by(district) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm = T)) %>%
    mutate(rank = rank(-mean.rainfall, ties.method = 'min')) %>%
    arrange(rank) %>%
    filter(district %in% c('송파구', '강남구', '중랑구'))
  district mean.rainfall rank
1 중랑구   116.75000      4  
2 송파구    91.89474      7  
3 강남구    81.78947     13  

arrangedesc을 이용해 평균 강수량으로 내림차순을 한다.

climates %>%
    group_by(district) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm = T)) %>%
    mutate(rank = rank(-mean.rainfall, ties.method = 'min')) %>%
    arrange(rank) %>%
    filter(district %in% c('송파구', '강남구', '중랑구')) %>%
    arrange(desc(mean.rainfall))
  district mean.rainfall rank
1 중랑구   116.75000      4  
2 송파구    91.89474      7  
3 강남구    81.78947     13  

평균 강수량이 아닌 랭크를 내림차순 정렬 시켜도 동일한 결과가 나온다.

climates %>%
    group_by(district) %>%
    summarise(mean.rainfall = mean(rainfall, na.rm = T)) %>%
    mutate(rank = rank(-mean.rainfall, ties.method = 'min')) %>%
    arrange(rank) %>%
    filter(district %in% c('송파구', '강남구', '중랑구')) %>%
    arrange(rank)
  district mean.rainfall rank
1 중랑구   116.75000      4  
2 송파구    91.89474      7  
3 강남구    81.78947     13