본 포스팅은 R for Data Science를 기반으로 작성되었습니다.
1. 소개
“The simple graph has brought more information to the data analyst’s mind than any other device.”
— John Tukey —
이 장에서는 ggplot2 패키지를 사용하여 데이터를 시각화하는 방법을 알아보겠습니다. R에는 그래프를 만들기 위한 여러 패키지가 있지만 ggplot2는 가장 훌륭하고 다재다능한 시스템 중 하나입니다. ggplot2는 그래프를 설명하고 작성하기 위한 일관된 시스템인 그래픽 문법을 구현합니다. ggplot2를 사용하면 하나의 시스템을 학습하고 여러 곳에 적용하여 더 빠르게 수행할 수 있습니다. 시작하기 전에 ggplot2에 대해 더 자세히 알고 싶다면 “The Layered Grammar of Graphics”을 보시면 됩니다.
1.1. 전제조건
이번 장에서는 Tidyverse의 핵심 멤버 패키지 중 하나인 ggplot2에 초점을 맞춥니다. 이 장에서 사용할 data set, 도움말 페이지 및 기능에 접근하려면 아래 코드를 실행하여 tidyverse를 로드하셔야 합니다.
이 한 줄의 코드는 tidyverse 패키지를 R로 로드합니다. 또한 기본 R의 함수(또는 로드했을 수 있는 다른 패키지의 함수)와 충돌하는 Tidyverse의 함수를 알려줍니다.
이 코드를 실행하고 "'tidyverse'라는 패키지가 없습니다"라는 오류 메시지가 나타나면 먼저 설치한 다음 library()를 다시 한번 실행해야 합니다.
install.packages("tidyverse")
library(tidyverse)
패키지는 한 번만 설치하면 되지만 R의 새 세션을 시작할 때마다 다시 로드해야 합니다.
함수(또는 데이터 세트)가 어디에서 왔는지 명시해야 하는 경우 특수 형식 package::function()을 사용합니다. 예를 들어, ggplot2::ggplot()은 ggplot2 패키지의 ggplot() 함수를 사용하고 있음을 알려줍니다.
2. 첫 번째 단계
첫 번째 그래프를 사용하여 아래 질문에 답해 보겠습니다. 큰 엔진을 가진 자동차가 작은 엔진을 가진 자동차보다 더 많은 연료를 사용할까요? 엔진 크기와 연비 사이의 관계는 어떻게 보입니까? 양의 상관관계인가요? 아니면 음의 상관관계인가요? 선형 관계인가요? 비선형 관계인가요?
2.1. The mpg 데이터 프레임
ggplot2(ggplot2::mpg라고도 함)에 있는 mpg 데이터 프레임으로 위의 질문에 답을 구할 수 있습니다. 데이터 프레임은 변수(열)와 관측치(행)의, 문자형 변수와 숫자형 변수가 혼합되어 있는 직사각형 형태의 모음입니다. mpg 데이터에는 미국 환경 보호국이 38개의 자동차 모델에 대해 수집한 내용이 포함되어 있습니다.
mpg의 변수 중에는
- displ: 자동차의 엔진 크기(리터)
- hwy: 고속도로에서 자동차의 연비를 갤런당 마일(mpg)로 표시함. 연비가 낮은 자동차는 같은 거리를 주행할 때 연비가 높은 자동차보다 더 많은 연료를 소비함
mpg에 대해 자세히 알아보려면 ?mpg를 실행하여 도움말 페이지를 여십시오.
2.2. ggplot 생성하기
mpg data를 그래프로 표현하려면 아래 코드를 실행하여 x축에 displ 변수를 배치하고 y축에 hwy 변수를 배치합니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
이 그림은 엔진 크기(displ)와 연료 효율(hwy) 이 음의 상관관계가 있다는 것을 보여줍니다. 다시 말해서, 큰 엔진을 가진 자동차는 더 많은 연료를 사용합니다.
ggplot2를 사용하면 ggplot() 함수로 산점도를 그리기 시작합니다. ggplot()은 층(layer)을 추가할 수 있는 좌표계를 생성합니다. ggplot()의 첫 번째 인수는 그래프에서 사용할 data set입니다. 그래서 ggplot(data = mpg)는 빈 그래프를 생성하지만(위의 그림에서 검은 점들은 사라지고, 회색 바탕화면만 출력), 여기서는 표시하지 않겠습니다.
ggplot()에 하나 이상의 층(layer)을 추가하여 그래프를 완성합니다. geom_point() 함수는 플롯에 점 레이어를 추가하여 산점도를 생성합니다. ggplot2는 각각 다른 유형의 층(layer)를 그림에 추가하는 많은 기하 도형 함수와 함께 제공됩니다. 이 챕터를 통해 많은 것을 배우게 될 것입니다. ggplot2의 각 기하 함수는 mapping 인수를 사용합니다. 이는 data set의 변수가 시각적 속성에 매핑되는 방법을 정의합니다. mapping 인수는 항상 aes()와 쌍을 이루고 aes()의 x 및 y 인수는 x 및 y 축에 매핑할 변수를 지정합니다. ggplot2는 데이터 인수(이 경우 mpg data)에서 매핑된 변수를 찾습니다.
2.3. 그래프 템플릿
이 코드를 ggplot2로 그래프를 만들기 위한 재사용 가능한 템플릿으로 바꿔보죠. 그래프를 만들려면 아래 코드에서 괄호로 묶인 섹션을 data set, 기하 도형 함수 또는 매핑 모음으로 바꾸세요.
ggplot(data = <DATA>) +
<GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))
이 장의 나머지 부분에서는 이 템플릿을 완성하고 확장하여 다양한 유형의 그래프를 만드는 방법을 보여주도록 하겠습니다. <MAPPINGS> 컴포넌트부터 시작하겠습니다.
3. 미적 맵핑
“The greatest value of a picture is when it forces us to notice what we never expected to see.” — John Tukey
아래 그림에서 붉은색 타원 안에 있는 포인트 그룹(빨간색으로 강조 표시됨)은 선형 추세를 벗어나는 것 같습니다. 이 차량들은 예상보다 높은 주행 거리를 가지고 있습니다. 이 차들을 어떻게 설명할 수 있습니까?
만약 자동차가 하이브리드라고 가정해 볼까요? 이 가설을 테스트하는 한 가지 방법은 각 자동차의 클래스 값을 보는 것입니다. mpg data set의 클래스 변수는 자동차를 소형, 중형 및 SUV와 같은 그룹으로 분류합니다. 외곽 지점이 하이브리드인 경우 소형차 또는 아마도 소형차로 분류되어야 합니다(이 데이터는 하이브리드 트럭 및 SUV가 대중화되기 전에 수집되었다는 사실을 기억하세요).
클래스와 같은 세 번째 변수를 미학에 매핑하여 2차원 산점도에 추가할 수 있습니다. 미학은 플롯에 있는 개체들의 시각적 속성입니다. 미학에는 포인트의 크기, 모양 또는 색상과 같은 것들이 포함됩니다. 미적 속성 값을 변경하여 포인트(아래와 같은)를 다양한 방식으로 표시할 수 있습니다. 앞에서 이미 데이터를 설명하기 위해 "값"이라는 단어를 사용하고 있으므로 미적 속성을 설명하기 위해 "수준"이라는 단어를 사용하겠습니다. 여기에서 포인트의 크기, 모양 및 색상 수준을 변경하여 포인트를 작게, 삼각형 또는 파란색으로 만듭니다.
플롯의 미학을 데이터 세트의 변수에 매핑하여 데이터에 대한 정보를 전달할 수 있습니다. 예를 들어 포인트 색상을 클래스 변수에 매핑하여 각 자동차의 클래스를 표시할 수 있습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = class))
미학을 변수에 매핑하려면 미학 이름을 aes() 내부의 변수 이름에 연결합니다. ggplot2는 스케일링이라고 하는 프로세스를 변수의 각 고유 값에 고유한 수준의 미학(여기서는 고유한 색상)을 자동으로 할당합니다. ggplot2는 또한 어떤 수준이 어떤 값에 해당하는지 설명하는 범례를 추가합니다.
색상을 보면 특이한 점의 대부분이 2인승 차량임을 알 수 있습니다. 이 차는 하이브리드처럼 보이지 않고 스포츠카입니다. 스포츠카는 SUV, 픽업트럭과 같은 대형 엔진을 탑재하고 있지만 중형, 소형차와 같은 소형 차체로 연비를 향상시킵니다. 이 자동차들은 큰 엔진을 가지고 있기 때문에 하이브리드가 아닐 가능성이 큽니다.
위의 예에서 우리는 색상 미학에 클래스를 매핑했지만 같은 방식으로 크기 미학에 클래스를 매핑할 수 있습니다. 이 경우 각 포인트의 크기는 클래스 소속을 나타냅니다. 정렬되지 않은 변수(클래스)를 정렬된 미학(크기)에 매핑하는 것은 좋은 생각이 아니기 때문에 여기서 경고를 받습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, size = class))
#> Warning: Using size for a discrete variable is not advised.
또는 점의 투명도를 제어하는 알파 미학 또는 점의 모양을 제어하는 모양 미학에 클래스를 매핑할 수 있습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, alpha = class))
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, shape = class))
SUV에 무슨 일이 일어났나요? ggplot2는 한 번에 6개의 모양만 사용합니다. 모양 미학을 디폴트로 사용하면 추가 그룹이 표시되지 않습니다. aes() 함수는 레이어에서 사용하는 각각의 미학적 매핑을 모아서 레이어의 매핑 인수에 전달합니다. 구문은 x 및 y에 대한 유용한 통찰력을 강조합니다. 점의 x 및 y 위치는 데이터에 대한 정보를 표시하기 위해 변수에 매핑할 수 있는 그 자체로서 속성이 미학입니다.
미학을 매핑하면 ggplot2가 나머지를 처리합니다. 미학과 함께 사용할 합리적인 척도를 선택하고 수준과 값 간의 매핑을 설명하는 범례를 구성합니다. x 및 y 미학의 경우 ggplot2는 범례를 생성하지 않지만 눈금과 레이블이 있는 축 선을 생성합니다. 축 선은 범례 역할을 합니다. 위치와 값 간의 매핑을 설명합니다.
형상의 미적 속성을 수동으로 설정할 수도 있습니다. 예를 들어, 플롯의 모든 점을 파란색으로 만들 수 있습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), color = "blue")
여기서 색상은 변수에 대한 정보를 전달하지 않고 플롯의 모양만 변경합니다. 미학을 수동으로 설정하려면 이름으로 미학을 geom 함수의 인수로 설정하세요. aes() 구문 밖에서 작성하셔야 합니다. 해당 미학에 맞는 수준을 선택해야 합니다.
- 문자열로 된 색상의 이름
- 점의 크기(mm)
- 아래와 같이 숫자로 나타낸 점의 모양
4. 주의사항
R 코드를 실행하기 시작하면 문제가 발생할 수 있습니다. 걱정하지 마세요. 누구에게나 발생하는 일입니다.
실행 중인 코드를 책에 있는 코드와 주의 깊게 비교하는 것부터 시작하는 게 좋습니다. R은 매우 까다로우며 잘못 배치된 문자가 모든 차이를 만들 수 있습니다. "(" 와 ")"가 쌍을 잘 이루고 있는지, "와 "과 쌍을 이루는지 확인하세요. 코드를 실행해도 아무 일도 일어나지 않는 경우가 있습니다. 콘솔 창의 왼쪽을 확인해 보세요. +이면 R이 사용자가 완전한 표현식을 입력했다고 생각하지 않고 사용자가 완료하기를 기다리고 있음을 의미합니다. 이 경우 일반적으로 현재 명령 처리를 중단하기 위해 ESCAPE를 눌러 처음부터 다시 시작하는 것이 쉬울 수 있습니다.
ggplot2 그래픽을 생성할 때 흔히 발생하는 문제 중 하나는 +를 잘못된 위치에 넣는 것입니다. +는 시작이 아니라 줄 끝에 와야 합니다. 즉, 실수로 다음과 같은 코드를 작성하지 않았는지 확인하셔야 합니다.
ggplot(data = mpg)
+ geom_point(mapping = aes(x = displ, y = hwy))
그래도 문제가 해결되지 않으면 도움을 받으십시오. 콘솔 창에서 ?함수 이름을 실행하거나 RStudio에서 함수 이름을 선택하고 F1을 눌러 R 함수에 대한 도움말을 얻을 수 있습니다. 도움이 되지 않는다고 걱정하지 마십시오. 대신 수행하려는 작업과 일치하는 예제 코드를 찾으세요.
5. 여러 면(Facets) 생성
부가적인 변수를 또 추가하는 한 가지 방법은 미학을 사용하는 것입니다. 범주형 변수에 특히 유용한 또 다른 방법은 플롯을 패싯으로 나누는 것입니다. 하위 플롯은 각각 데이터의 하위 집합을 하나씩 표시합니다.
단일 변수로 플롯을 facet 하려면 facet_wrap() 함수를 사용하세요. facet_wrap()의 첫 번째 인수는 수식이어야 하며, ~ 뒤에 변수 이름이 따라옵니다(여기서 "formula"는 "equation"의 동의어가 아니라 R의 데이터 구조 이름입니다). facet_wrap() 함수에 전달하는 변수는 이산적이어야 합니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_wrap(~ class, nrow = 2)
두 변수의 조합에 대한 플롯을 facet 하려면 플롯 호출에 facet_grid()를 추가하세요. facet_grid() 함수의 첫 번째 인수도 공식입니다. 이번에는 수식에 ~로 구분된 두 개의 변수 이름이 포함되어야 합니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ cyl)
행 또는 열 차원에서 facet을 사용하지 않으려면. 변수 이름 대신 . 를 사용하세요. 예를 들면, + facet_grid(. ~ cyl) 이렇게요.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(drv ~ .)
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
facet_grid(. ~ cyl)
6. 기하학적 개체(Geometric objects)
아래 두 그림은 어떻게 비슷합니까?
두 그림 모두 동일한 x 변수, 동일한 y 변수를 포함하며 둘 다 동일한 데이터를 설명합니다. 그러나 그림의 모양은 동일하지 않습니다. 각 그림은 다른 시각적 개체를 사용하여 데이터를 나타냅니다. ggplot2 구문에서는 서로 다른 도형(geom)을 사용한다고 말합니다.
기하 도형은 그림이 데이터를 나타내는 데 사용하는 기하학적 개체입니다. 사람들은 종종 그림이 사용하는 도형 유형으로 플롯을 설명합니다. 예를 들어, 막대 차트는 막대 기하 도형을 사용하고, 꺾은선형 차트는 선 기하 도형을 사용하고, 상자 그림은 상자 그림 기하 도형을 사용하는 식입니다. 산점도는 추세를 나타내지 못하고, 점 도형을 사용합니다. 위에서 볼 수 있듯이 다른 기하 도형을 사용하여 동일한 데이터를 그릴 수 있습니다. 왼쪽 그림은 점 기하 도형을 사용하고 오른쪽의 그림은 데이터에 맞는 부드러운 선인 부드러운 기하 도형을 사용합니다.
그림에서 기하 도형을 변경하려면 ggplot()에 추가한 기하 도형 함수를 변경합니다. 예를 들어 위의 플롯을 만들려면 다음 코드를 사용할 수 있습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy))
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
ggplot2의 모든 기하 함수는 매핑 인수를 사용합니다. 그러나 모든 미학이 모든 기하학에서 작동하는 것은 아닙니다. 점의 모양은 설정할 수 있지만 선의 "모양"은 설정할 수 없습니다. 반면에 선의 선종류를 설정할 수 있습니다. geom_smooth() 함수는 선종류에 매핑하는 변수의 고유한 값마다 다른 선종류를 사용하여 다른 선을 그립니다.
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv))
여기서 geom_smooth() 함수는 자동차의 구동계를 설명하는 drv 값에 따라 자동차를 세 줄로 구분합니다. 한 줄은 값이 4인 모든 점을 설명하고, 한 줄은 f 값을 가진 모든 점을 설명하고, 한 줄은 r 값을 가진 모든 점을 설명합니다. 여기서 4는 4륜 구동, f는 전륜구동, r은 후륜구동을 의미합니다.
이것이 이상하게 들리면 원시 데이터 위에 선을 오버 레이한 다음 drv에 따라 모든 것을 색칠하여 더 명확하게 만들 수 있습니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy, color = drv)) +
geom_smooth(mapping = aes(x = displ, y = hwy, linetype = drv, color = drv))
이 그림에는 동일한 그래프에 두 개의 기하 도형이 포함되어 있습니다. 이것이 당신을 흥분시킨다면, 버클을 채우십시오. 곧 동일한 플롯에 여러 기하 도형을 배치하는 방법을 배울 겁니다.
ggplot2는 40개 이상의 도형을 제공하고 확장 패키지는 더 많은 도형을 제공합니다(https://exts.ggplot2.tidyverse.org/gallery/ 사이트 참고). 포괄적인 개요를 얻는 가장 좋은 방법은 http://rstudio.com/resources/cheatsheets에서 찾을 수 있는 ggplot2 치트 시트입니다. 단일 기하 도형에 대해 자세히 알아보려면 ?geom_smooth 도움말을 사용하세요.
geom_smooth() 함수와 같은 많은 기하 도형은 단일 기하 객체를 사용하여 여러 행의 데이터를 표시합니다. 이러한 기하 도형의 경우 그룹 미학을 범주형 변수로 설정하여 여러 개체를 그릴 수 있습니다. ggplot2는 그룹화 변수의 각 고유 값에 대해 별도의 객체를 그립니다. 실제로 ggplot2는 미학을 개별 변수에 매핑할 때마다 이러한 도형에 대한 데이터를 자동으로 그룹화합니다(선종류 예제에서와 같이). 그룹 미학 자체가 범례나 구별되는 특징을 형상에 추가하지 않기 때문에 이 기능에 의존하는 것이 편리합니다.
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy))
ggplot(data = mpg) +
geom_smooth(mapping = aes(x = displ, y = hwy, group = drv))
ggplot(data = mpg) +
geom_smooth( mapping = aes(x = displ, y = hwy, color = drv), show.legend = FALSE )
동일한 그림에 여러 기하 도형을 표시하려면 ggplot()에 여러 기하 함수를 추가하시면 됩니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy)) +
geom_smooth(mapping = aes(x = displ, y = hwy))
그러나 이러한 방법은 우리 코드에 많은 중복을 가져옵니다. hwy 대신 cty를 표시하도록 y축을 변경한다고 해보죠. 두 곳에서 변수를 똑같이 변경해야 하고 하나를 빼놓고 잊어버릴 수 있습니다. 매핑 세트를 ggplot()에 전달하면 이러한 유형의 반복을 피할 수 있습니다. ggplot2는 이러한 매핑을 그래프의 각 도형에 적용되는 전역 매핑으로 처리합니다. 즉, 아래 코드는 위의 코드와 동일한 그림을 생성합니다.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point() +
geom_smooth()
Geom 함수에 매핑을 배치하면 ggplot2가 이를 레이어에 대한 로컬 매핑으로 처리합니다. 이 매핑을 사용하여 해당 레이어에 대한 전역 매핑만 확장하거나 덮어씁니다. 이를 통해 다른 레이어에서 다른 미학을 표시할 수 있습니다.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth()
동일한 아이디어를 사용하여 각 레이어에 대해 다른 데이터를 지정할 수 있습니다. 여기에서 부드러운 선은 mpg 데이터 세트의 하위 집합인 소형차만 표시합니다. geom_smooth() 함수의 로컬 데이터 인수는 해당 레이어에 대해서만 ggplot()의 글로벌 데이터 인수를 재정의합니다.
ggplot(data = mpg, mapping = aes(x = displ, y = hwy)) +
geom_point(mapping = aes(color = class)) +
geom_smooth(data = filter(mpg, class == "subcompact"), se = FALSE)
( filter() 함수는 데이터 변환에 대해 배울 때 알아볼 것입니다. 지금은 이 명령이 소형차만 선택한다는 것만 알아두죠.)
7. 통계적 변환
이제, 막대 차트(bar chart)를 살펴보겠습니다. 바 차트는 간단해 보이지만 그림에 대해 미묘한 것을 드러내기 때문에 흥미롭습니다. geom_bar() 함수로 그려진 기본 막대 차트를 고려합니다. 다음 차트에는 cut으로 그룹화된 다이아몬드 data set의 총 다이아몬드 수가 표시됩니다. 다이아몬드 data set는 ggplot2로 제공되며 각 다이아몬드의 가격, 캐럿, 색상, 선명도 및 컷을 포함하여 ~ 54,000 개의 다이아몬드에 대한 정보가 포함되어 있습니다. 차트는 낮은 품질의 컷보다 높은 품질의 컷으로 더 많은 다이아몬드를 사용할 수 있음을 보여줍니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut))
x축은 다이아몬드의 컷을 표시합니다. y축에서는 건수를 표시하지만 건수는 다이아몬드의 변수가 아닙니다. 건수는 어디에서 왔을까요? 산점도와 같은 많은 그래프는 데이터 집합의 raw 값을 표시합니다. 막대 차트와 같은 다른 그래프는 표현할 새 값을 계산합니다.
- 막대 차트, 히스토그램 및 빈도 다각형: 데이터를 구간화한 다음 각 구간에 속하는 포인트 수인 구간 수 표시
- smoother는 모델을 데이터에 맞춘 다음 모델에서의 예측값 표현
- boxplots는 분포에 대한 요약 값을 계산한 다음 특별한 형식이 지정된 상자 표시
그래프의 새 값을 계산하는 데 사용되는 방법을 통계적 변환의 줄임말인 통계라고 합니다. 아래 그림은 이 프로세스가 geom_bar()와 함께 작동하는 방식을 설명합니다.
stat 인수의 기본값을 검사하여 도형이 사용하는 통계를 알 수 있습니다. 예를 들어, ?geom_bar는 stat의 기본값이 "count"임을 보여줍니다. 이는 geom_bar() 함수가 stat_count() 함수를 사용함을 의미합니다. stat_count() 함수는 geom_bar()와 동일한 페이지에 문서화되어 있으며 아래로 스크롤하면 "계산된 변수"라는 섹션을 찾을 수 있습니다. 이는 count 및 prop의 두 가지 새로운 변수를 계산하는 방법을 설명합니다. 일반적으로 기하 도형과 통계를 서로 바꿔서 사용할 수 있습니다. 예를 들어, geom_bar() 함수 대신 stat_count() 함수를 사용하여 이전 플롯을 다시 만들 수 있습니다.
ggplot(data = diamonds) +
stat_count(mapping = aes(x = cut))
이것은 모든 기하가 기본 통계를 가지고 있기 때문에 작동합니다. 모든 통계에는 기본 도형이 있습니다. 이는 기본 통계 변환에 대해 걱정하지 않고 일반적으로 기하 도형을 사용할 수 있음을 의미합니다. 통계를 명시적으로 사용해야 하는 세 가지 이유가 있습니다.
- 기본 통계를 재정의할 수 있습니다. 아래 코드에서 저는 geom_bar() 함수의 통계를 count(기본값)에서 identity로 변경합니다. 이를 통해 막대의 높이를 y 변수에 맵핑시킬 수 있습니다. 불행히도 사람들이 아무렇게나 막대 차트에 대해 이야기할 때 막대의 높이가 이미 데이터에 있는 이러한 유형의 막대 차트 또는 행을 계산하여 막대의 높이가 생성되는 이전 막대 차트를 참조할 수 있습니다.
demo <-tribble(
~cut, ~freq,
"Fair", 1610,
"Good", 4906,
"Very Good", 12082,
"Premium", 13791, "Ideal", 21551 )
ggplot(data = demo) +
geom_bar(mapping = aes(x = cut, y = freq), stat = "identity")
(<- 또는 tribble()을 활용한 data set과 관련된 내용은 tibble 포스팅을 참고하시면 됩니다.)
- 변환된 변수에서 미학으로의 기본 매핑을 재정의할 수 있습니다. 예를 들어 개수 대신 비율 막대 차트를 표시할 수 있습니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, y = stat(prop), group = 1))
통계에 의해 계산된 변수를 찾으려면 "computed variables"라는 제목의 도움말 섹션을 찾으십시오.
- 코드의 통계 변환에 더 많은 관심을 기울이고 싶을 수 있습니다. 예를 들어, 각각의 고유한 x 값에 대한 y 값을 요약하는 stat_summary()를 사용하여 계산 중인 요약에 주의를 끌 수 있습니다.
ggplot(data = diamonds) +
stat_summary(
mapping = aes(x = cut, y = depth),
fun.min = min,
fun.max = max,
fun = median
)
ggplot2는 사용할 수 있는 20개 이상의 통계를 제공합니다. 각 통계는 모두 함수이므로 ?stat_bin 와 같은 일반적인 방법으로 도움을 받을 수 있습니다. 전체 통계 목록을 보려면 ggplot2 치트 시트를 사용해 보세요.
8. 위치 조정
막대 차트와 관련된 또 하나의 마법이 있습니다. 색상 미학을 사용하거나 더 유용하게는 채우기를 사용하여 막대 차트에 색상을 지정할 수 있습니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, colour = cut))
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = cut))
채우기 미학을 선명도와 같은 다른 변수에 매핑하면 어떻게 되는지 확인하세요. 막대는 자동으로 쌓입니다. 각 색상 사각형은 절단과 선명도의 조합을 나타냅니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity))
누적은 position 인수로 지정된 위치 조정에 의해 자동으로 수행됩니다. 누적 막대 차트를 원하지 않는 경우 "identity", "dodge" 또는 "fill"의 세 가지 다른 옵션 중 하나를 사용할 수 있습니다.
- position = "identity"는 그래프 콘텍스트에서 정확히 해당 위치에 각 개체를 배치합니다. 막대와 겹치기 때문에 막대에는 그다지 유용하지 않은 옵션입니다. 겹치는 것을 보려면 alpha를 작은 값으로 설정하여 막대를 약간 투명하게 만들거나 fill = NA로 설정하여 완전히 투명하게 만들어야 합니다.
ggplot(data = diamonds, mapping = aes(x = cut, fill = clarity)) +
geom_bar(alpha = 1/5, position = "identity")
ggplot(data = diamonds, mapping = aes(x = cut, colour = clarity)) +
geom_bar(fill = NA, position = "identity")
'identity' 위치 조정은 기본값인 점과 같은 2D 기하 도형에 더 유용합니다.
- position = "fill"은 누적과 같이 작동하지만 누적 막대의 각 세트를 동일한 높이로 만듭니다. 이렇게 하면 그룹 간의 비율을 더 쉽게 비교할 수 있습니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "fill")
position = "dodge"는 겹치는 개체를 서로 바로 옆에 배치합니다. 이렇게 하면 개별 값을 더 쉽게 비교할 수 있습니다.
ggplot(data = diamonds) +
geom_bar(mapping = aes(x = cut, fill = clarity), position = "dodge")
막대 차트에는 유용하지 않은 조정 유형이 하나 더 있지만 산점도에는 매우 유용할 수 있습니다. 첫 번째 산점도(hwy와 displ의 관계 그림)를 기억하세요. data set에 234개의 관측값이 있음에도 플롯에 126개 포인트만 표시된다는 것을 알고 계셨습니까?
hwy 및 displ 값은 반올림되어 점이 그리드에 나타나고 많은 점이 서로 겹칩니다. 이 문제를 오버 플로팅(overplotting)이라고 합니다. 이 배열은 데이터의 질량이 어디에 있는지 보기 어렵게 만듭니다. 데이터 포인트가 그래프 전체에 균등하게 분산되어 있습니까? 아니면 109개의 값을 포함하는 hwy와 displ의 특별한 조합이 하나 있습니까?
위치 조정을 "jitter"로 설정하여 이 그리딩을 방지할 수 있습니다. position = "jitter"는 각 지점에 소량의 임의 노이즈를 추가합니다. 두 지점이 동일한 양의 임의 노이즈를 수신할 가능성이 없기 때문에 이는 지점을 분산시킵니다.
ggplot(data = mpg) +
geom_point(mapping = aes(x = displ, y = hwy), position = "jitter")
무작위성을 추가하는 것은 그림을 개선하는 이상한 방법처럼 보이지만 소규모에서는 그래프의 정확도가 떨어지지만 대규모에서는 그래프가 더 잘 드러납니다. 이것은 매우 유용한 작업이기 때문에 ggplot2에는 geom_point(position = "jitter")의 약어인 geom_jitter() 함수가 있습니다. 위치 조정에 대해 자세히 알아보려면 각 조정과 관련된 도움말 페이지(?position_dodge, ?position_fill, ?position_identity, ?position_jitter 및 ?position_stack)를 찾아보시면 됩니다.
9. 좌표계(Coordinate systems)
좌표계는 아마도 ggplot2에서 가장 복잡한 부분일 것입니다. 기본 좌표계는 x 및 y 위치가 독립적으로 작용하여 각 점의 위치를 결정하는 데카르트 좌표계입니다. 때때로 도움이 되는 다른 좌표계가 많이 있습니다.
- coord_flip() 함수는 x축과 y축을 전환합니다. 이것은 수평 상자 그림을 원하는 경우에 유용합니다. 라벨이 긴 경우에도 유용합니다. 라벨이 길면 x축에서 겹치지 않고 맞추기가 어렵습니다.
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot()
ggplot(data = mpg, mapping = aes(x = class, y = hwy)) +
geom_boxplot() +
coord_flip()
- coord_quickmap() 함수는 지도의 종횡비를 올바르게 설정합니다. 이것은 ggplot2로 공간 데이터를 플로팅 하는 경우 매우 중요합니다.
nz <- map_data("nz")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black")
ggplot(nz, aes(long, lat, group = group)) +
geom_polygon(fill = "white", colour = "black") +
coord_quickmap()
- coord_polar()는 극좌표를 사용합니다. 극좌표는 막대 차트와 Coxcomb 차트 사이의 흥미로운 연결을 보여줍니다.
bar <- ggplot(data = diamonds) +
geom_bar(
mapping = aes(x = cut, fill = cut),
show.legend = FALSE,
width = 1
) +
theme(aspect.ratio = 1) +
labs(x = NULL, y = NULL)
bar + coord_flip()
bar + coord_polar()
10. 그래픽의 계층화된 문법
이전 섹션에서는 산점도, 막대 차트 및 상자 그림을 만드는 방법보다 훨씬 더 많은 것을 배웠습니다. ggplot2로 모든 유형의 플롯을 만드는 데 사용할 수 있는 기초를 배웠습니다. 이를 확인하기 위해 위치 조정, 통계, 좌표계 및 패싯을 코드 템플릿에 추가해 보겠습니다.
ggplot(data = <DATA>) +
<GEOM_FUNCTION>(
mapping = aes(<MAPPINGS>),
stat = <STAT>,
position = <POSITION>
) +
<COORDINATE_FUNCTION> +
<FACET_FUNCTION>
우리의 새 템플릿은 템플릿에 나타나는 괄호 단어인 7개의 매개변수를 사용합니다. 실제로는 ggplot2가 데이터, 매핑 및 기하 도형 함수를 제외한 모든 항목에 대해 유용한 기본값을 제공하기 때문에 그래프를 만들기 위해 7개의 매개변수를 모두 제공할 필요가 거의 없습니다.
템플릿의 7개 매개변수는 플롯을 작성하기 위한 그래픽의 문법을 구성합니다. 그래픽의 문법은 데이터 세트, 기하학, 매핑 세트, 통계, 위치 조정, 좌표계 및 패싯 체계의 조합으로 모든 플롯을 고유하게 설명할 수 있다는 통찰력을 기반으로 합니다.
이것이 어떻게 작동하는지 보려면 처음부터 기본 플롯을 구축하는 방법을 고려해 보세요. 데이터 세트로 시작한 다음 표시하려는 정보(통계 포함)로 변환할 수 있습니다.
다음으로, 변환된 데이터의 각 관찰을 나타내는 기하학적 개체를 선택할 수 있습니다. 그런 다음 기하 도형의 미적 속성을 사용하여 데이터의 변수를 나타낼 수 있습니다. 각 변수의 값을 미학 수준에 매핑합니다.
그런 다음 도형 배치할 좌표계를 선택합니다. x 및 y 변수의 값을 표시하기 위해 객체의 위치(자체 미적 속성)를 사용합니다. 이 시점에서 완전한 그래프를 갖게 되지만 좌표계 내에서 기하 도형의 위치를 추가로 조정(위치 조정)하거나 그래프를 서브플롯으로 분할(패싯)할 수 있습니다. 하나 이상의 추가 레이어를 추가하여 플롯을 확장할 수도 있습니다. 여기서 각 추가 레이어는 데이터 세트, 기하학, 매핑 세트, 통계 및 위치 조정을 사용합니다.
이 방법을 사용하여 상상하는 모든 플롯을 작성할 수 있습니다. 즉, 이 장에서 배운 코드 템플릿을 사용하여 수십만 개의 고유한 플롯을 만들 수 있습니다.
R의 가장 파워풀한 기능 중 하나가 그래픽입니다. 기본적인 문법 체계를 익히고, 원리를 이해하고, 조금만 실습하면 멋진 그래프를 만들어 내실 수 있을 겁니다.
'R 프로그래밍 > R advance' 카테고리의 다른 글
와이드 포맷과 롱 포맷 간 데이터 변환 (0) | 2021.12.28 |
---|---|
[R그래픽스]커뮤니케이션을 위한 그래픽 (0) | 2021.07.20 |
[R데이터다루기]데이터 변환 (0) | 2021.07.18 |
[R데이터구조]Tibble (0) | 2021.07.15 |
[R변수형식]날짜와 시간 데이터 (0) | 2021.07.14 |
댓글