ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • R 프로그래밍 9 - dplyr을 활용하여 깔끔한 코드로 데이터 전처리하기(filter, arrange, mutate, select, summarise, group_by, %>%)
    데이터분석/R 2021. 12. 14. 23:58
    반응형

    https://kbkb456.tistory.com/62

     

    R 프로그래밍 8 - R 데이터 프레임을 피벗 테이블 처럼 활용하기(dcast, melt)

    오늘은 R의 데이터 프레임을 피벗테이블처럼 활용하는 법에 대해서 알아보도록 하겠습니다. 여러분 피벗테이블은 왜 쓸까요? 바로 데이터프레임을 원하는 데로 길게(long format)하거나 넓게(wide fo

    kbkb456.tistory.com

    저번 시간에는 reshape2를 활용해서 데이터를 피봇팅 하는 방법에 대해서 알아봤습니다. 오늘은 r 데이터 전처리에서 널리 활용되는 dplyr에 대해서 알아보도록 하겠습니다.

     

    dplyr 패키지?

    reshape2 패키지와 마찬가지로 데이터 전처리에 특화된 R패키지입니다. 현재는 tidyverse 패키지 묶음에 포함되어 있는 패키지로 "너네는 편하게 코딩해 복잡한 계산을 내가 할께" 라는 철학을 가지고 있습니다.

     

    실제로 문법은 쉽지만 내부는 C++로 작성되어 불필요한 함수를 불러오지 않아 처리속도는 빠른 편입니다.

     

    https://www.tidyverse.org/

     

    Tidyverse

    The tidyverse is an integrated collection of R packages designed to make data science fast, fluid, and fun.

    www.tidyverse.org

    dplyr 말고도 tidyverse에는 다양한 패키지가 존재합니다. 잘 활용하면 r로 데이터 분석할 때 많은 도움을 받을 수 있습니다.

     

    dplyr 패키지 사용법

     

    1. 패키지 설치 및 불러오기

    #패키지 설치
    install.packages("dplyr")
    
    #패키지 불러오기
    library(dplyr)

    해당 코드로 dplyr 패키지를 현재 r 파일에 불러올 수 있습니다.

     

    2. 샘플 데이터 생성 코드

    #데이터 프레임생성
    df <- data.frame(student=c('철수','영수','금수'), 
                     language=c(90, 85, 100, 95, 90, 100),
                     english=c(70, 80, 100,75, 85, 85),
                     math=c(85, 100, 90, 80, 100, 90),
                     test_type = c('중간고사','중간고사','중간고사','기말고사','기말고사','기말고사'))

     

    샘플 데이터 view

    dplyr 샘플데이터

    철수, 영수, 금수의 국어, 영어, 수학 점수를 가지고 데이터 전처리를 해봅시다.

     

    3. dplyr의 주요 함수

    함수이름 문법 역할
    filter - filter(데이터 프레임, 조건) 데이터를 조건에 맞게 필터링 해줌
    arrange - 오름차순 : arrange(데이터 프레임,정렬하기 원하는 컬럼)
    - 내림차순 : arrange(데이터 프레임,desc(정렬하기 원하는 컬럼))
    데이터를 정렬를 원하는 컬럼을 기준으로 정렬해줌
    select - select(데이터 프레임, 원하는컬럼1,컬럼2 ...)
    - select(데이터 프레임, 원하는컬럼1:원하는컬럼끝까지)
    데이터 프레임에서 내가 원하는 컬럼을 선택해서 가져옴
    mutate - mutate(데이터 프레임, 추가될 컬럼명 = 추가하고 싶은 데이터) 기존데이터 프레임에 추가하고싶은 데이터를 추가해서 컬럼으로 넣어 줌
    summrise - summarise(데이터프레임, 계산된 컬럼명 = 집계함수(컬럼))  mean, sd, var, median, max, min등 함수를 지정해서 기초통계량을 구해 줌

    하나씩 알아보도록 하겠습니다.

     

    filter

    예시 데이터에서 수학 85점 이상부터 데이터를 가져오고 싶다고 하면 어떻게 처리할 수 있을까요?

     

    코드

    #필터링
    filter(df,math >= 85)

     

    실행결과

    r dplyr filter

    85점 미만의 수학 점수는 사라진 것을 알 수 있습니다.

     

    arrange

    예시 데이터에서 수학 점수를 기준으로 데이터 프레임을 오름차순 정렬하고 싶다면 어떻게 할 수 있을까요?

     

    코드

    #오름차순 정렬
    arrange(df,math)

    실행결과

    r dplyr arrange1

     

    그럼 내림차순으로 정렬하고 싶다면 어떻게 할까요?

     

    코드

    #내림 차순정렬
    arrange(df,desc(math))

    실행결과

    r dplyr arrange 2

     

    그럼 국어로 오름차순 한 뒤에 수학으로 내림차순을 하고 싶다면요?

     

    코드

    #컬럼 2개 정렬
    #맨 오른쪽 부터 정렬을 시작함
    arrange(df,desc(math),language)

     

    실행결과

    r dplyr arrange 3

    칼럼 2개 이상 정렬할 땐 오른쪽부터 정렬을 시작합니다. 그래서 맨 오른쪽부터 가장 먼저 정렬할 칼럼을 적어주시면 됩니다.

     

    select

    데이터에서 수학, 국어, 영어 칼럼만 선택해서 가져오고 싶으면 어떻게 할까요?

     

    코드

    #열선택
    select(df,math,language,english)

     

    실행결과

    r dplyr select

    원하는 칼럼 순서로 적어주시면 됩니다.

     

    인접한 칼럼인 경우 : 로 가져올 수 있습니다.

     

    코드

    #인접한컬럼은 이렇게가능
    select(df,math:language)

     

    실행결과

    r dplyr select 2

    코드상에는 english가 없었지만 math와 language 사이에 english가 있었기 때문에 같이 들어온 걸 볼 수 있습니다.

     

    mutate

    영어 + 수학 + 국어의 평균 점수 칼럼을 데이터 프레임에 추가하고 싶다면 어떻게 할 수 있을까요?

     

    코드

    #열추가
    mutate(df, avg_score = (math+language+english) / 3)

     

    실행결과

    r&nbsp; dplyr mutate

    이런 식으로 추가가 가능합니다.

     

    summarise

    전체 row수와 각 과목당 평균점수를 구하고 싶으면 어떻게 할까요?

     

    코드

    #집계
    summarise(df, #데이터프레임
              count = n(), #총 갯수
              avg_language = mean(language), #평균 국어
              avg_math = mean(math), # 평균 수학
              avg_english = mean(english) #평균 영어)

    실행결과

    r dplyr summarise

     

    chain 함수(%>%)와 group_by

    현실에서는 위처럼 단순한 계산이나 정렬을 원하는 상황보다 더욱 복잡한 상황을 요구하는 경우가 많습니다. 예를 들면 그룹별 집계 후에 정렬하거나 집계된 결과를 가지고 또 다른 처리를 해야 한다거나... 이런 경우 코드의 가독성을 잡아먹고 계산 로직을 짜는데 안 좋게 작용합니다. 이것을 해결하기 위해서 dplyr에서는 체인 함수를 제공합니다.

     

    chain?

    %>% 를 활용 함으로써 순차적으로 한 번에 연산하게 해 줘 중간에 생기는 임시 데이터 프레임의 개수를 최소화할 수 있도록 해주는 함수입니다.

     

    df에서 math, english, langue를 빼서 math로 내림차순 한 뒤 df2에 저장하는 걸 chain함수를 이용해서 표현하면 이렇게 됩니다.

     

    코드

    df2 <- df %>% select(math:language) %>% arrange(desc(math))
    df2

     

    실행결과

    r dplyr chain 함수

    체인 함수를 활용하게 되면 기존에 데이터 프레임을 넣지 않아도 함수가 알아서 인식해서 활용합니다. 그래서 더더욱 코드가 깨끗해집니다.

     

    group_by?

    group_by 함수는 데이터 프레임에서 그룹별 연산을 할 때 어떤 그룹으로 연산할지에 대한 그룹핑을 해주는 함수입니다.

     

    만약 test_type별 수학, 국어, 영어 각각의 평균을 알고 싶다면 어떻게 할 수 있을까요? group_by와 summarise를 같이 활용하면 이런 결과를 알 수 있습니다.

     

    코드

    df3 <- df %>% group_by(test_type) %>% summarise(count = n(),
                                                    avg_language = mean(language),
                                                    avg_math = mean(math),
                                                    avg_english = mean(english))

     

    실행결과

    r group_by summarise

    이런 식으로 데이터 결과를 알 수가 있습니다.

     

    만약 test_type별 수학, 국어, 영어 각각의 평균을 구한 후에 평균 수학 점수로 내림차순 정렬한다고 생각해봅시다.

     

    코드

    df4 <- df %>% group_by(test_type) %>% summarise(count = n(),
                            avg_language = mean(language),
                            avg_math = mean(math),
                            avg_english = mean(english)) %>% arrange(desc(avg_math))

     

    실행결과

    r group by summarise 2

     

    이런 식으로 chain 함수를 활용해서 summarise 결과로 나온 칼럼을 가지고도 추가 연산이 가능합니다.

     

    최종 코드

    #필요한 라이브러리
    library(dplyr)
    
    #데이터 프레임생성
    df <- data.frame(student=c('철수','영수','금수'), 
                     language=c(90, 85, 100, 95, 90, 100),
                     english=c(70, 80, 100,75, 85, 85),
                     math=c(85, 100, 90, 80, 100, 90),
                     test_type = c('중간고사','중간고사','중간고사','기말고사','기말고사','기말고사'))
    
    #필터링
    filter(df,math >= 85)
    
    #오름차순 정렬
    arrange(df,math)
    
    #내림 차순정렬
    arrange(df,desc(math))
    
    #컬럼 2개 정렬
    arrange(df,desc(math),language)
    
    #열선택
    select(df,math,language,english)
    
    #인접한컬럼은 이렇게가능
    select(df,math:language)
    
    #열추가
    mutate(df, avg_score = (math+language+english) / 3)
    
    #집계
    summarise(df,
              count = n(),
              avg_language = mean(language),
              avg_math = mean(math),
              avg_english = mean(english))
    
    #chain 함수 예시
    df2 <- df %>% select(math:language) %>% arrange(desc(math))
    
    
    #chain 함수 + group_by 예시
    df3 <- df %>% group_by(test_type) %>% summarise(count = n(),
                                                    avg_language = mean(language),
                                                    avg_math = mean(math),
                                                    avg_english = mean(english))
    
    df4 <- df %>% group_by(test_type) %>% summarise(count = n(),
                            avg_language = mean(language),
                            avg_math = mean(math),
                            avg_english = mean(english)) %>% arrange(desc(avg_math))
    반응형

    댓글

Designed by Tistory.