Description functions provided in ggplot2 Package
R에 입력된 데이터 세트를 전처리 과정을 통해 통계분석이 가능한 깔끔한 데이터로 정리하고 나면, 다양한 방법을 통해 데이터의 특성을 관찰하고 이해하는 과정이 필요하다. 이러한 과정을 “데이터 탐색”이라고 하며, 대표적인 데이터 탐색 방법은 요약 통계량과 시각화이다. 특히, 데이터 시각화는 도표를 비롯한 여러 수단을 통해 데이터에 숨겨진 정보를 명확하고 효과적으로 전달한다. 데이터 시각화를 수행하기 위해 R에서 널리 사용되는 Package는
ggplot2
(Ver. 3.3.5)이다. Packageggplot2
는 일관된 기초 문법을 가지고 있으며, 함수가 직관적이고 비교적 쉽게 완성도가 높은 그래프를 그릴 수 있다는 것이다. 따라서, 이 장에서는 Packageggplot2
를 이용하여 데이터 유형에 따른 다양한 시각화 방법에 대해 살펴본다.
# 2. p_load 이용하여 설치와 로드를 한꺼번에 에
# install.packages("pacman") # For p_load
pacman::p_load("ggplot2") # pacman::p_load : pacman 패키지의 p_load함수 사용NA
Result!
함수 p_load()
는 작성된 패키지가
설치 되어있지 않으면 설치 후 함수 library()
를 자동적으로
실행한다.
Package
ggplot2
에 내장되어 있는 데이터 “mpg”를 이용하여 시각화 방법에 대해 설명할 것이다. 데이터 “mpg”는 미국환경 보호국(US Environmental Protection Agency)에서 공개한 데이터로 1999~2008년 사이에 미국에서 출시된 자동차 234종의 연비 관련 정보를 담고 있으며, 변수는 다음과 같다.
tibble [234 x 11] (S3: tbl_df/tbl/data.frame)
$ manufacturer: chr [1:234] "audi" "audi" "audi" "audi" ...
$ model : chr [1:234] "a4" "a4" "a4" "a4" ...
$ displ : num [1:234] 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ...
$ year : int [1:234] 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ...
$ cyl : int [1:234] 4 4 4 4 6 6 6 4 4 4 ...
$ trans : chr [1:234] "auto(l5)" "manual(m5)" "manual(m6)" "auto(av)" ...
$ drv : chr [1:234] "f" "f" "f" "f" ...
$ cty : int [1:234] 18 21 20 21 16 18 18 18 16 20 ...
$ hwy : int [1:234] 29 29 31 30 26 26 27 26 25 28 ...
$ fl : chr [1:234] "p" "p" "p" "p" ...
$ class : chr [1:234] "compact" "compact" "compact" "compact" ...
# For 시각화화
data <- data %>%
mutate_if(is.character, as.factor) # 문자형 변수를 범주형 변수로 변환환
str(data)
tibble [234 x 11] (S3: tbl_df/tbl/data.frame)
$ manufacturer: Factor w/ 15 levels "audi","chevrolet",..: 1 1 1 1 1 1 1 1 1 1 ...
$ model : Factor w/ 38 levels "4runner 4wd",..: 2 2 2 2 2 2 2 3 3 3 ...
$ displ : num [1:234] 1.8 1.8 2 2 2.8 2.8 3.1 1.8 1.8 2 ...
$ year : int [1:234] 1999 1999 2008 2008 1999 1999 2008 1999 1999 2008 ...
$ cyl : int [1:234] 4 4 4 4 6 6 6 4 4 4 ...
$ trans : Factor w/ 10 levels "auto(av)","auto(l3)",..: 4 9 10 1 4 9 1 9 4 10 ...
$ drv : Factor w/ 3 levels "4","f","r": 2 2 2 2 2 2 2 1 1 1 ...
$ cty : int [1:234] 18 21 20 21 16 18 18 18 16 20 ...
$ hwy : int [1:234] 29 29 31 30 26 26 27 26 25 28 ...
$ fl : Factor w/ 5 levels "c","d","e","p",..: 4 4 4 4 4 4 4 4 4 4 ...
$ class : Factor w/ 7 levels "2seater","compact",..: 2 2 2 2 2 2 2 2 2 2 ...
여러 범주로 이루어진 범주형 데이터는 명목형 데이터와 순서형 데이터로 구분된다.
설명 | 예시 | |
---|---|---|
명목형 데이터 | 범주들 간에 순서척도가 없는 경우 | 거주지, 성별, 혈액형 |
순서형 데이터 | 범주들을 순서에 따라 나열할 수 있는 경우 | 학년, 만족도 |
※ 이 절에서는 명목명과 순서형 구분 없이 모두에게 잘 적용되는 그래프들을 살펴볼 것이다.
table()
을
이용하여 나타낼 수 있다.prop.table(도수분포표)
을 이용한다.# 변수 class의 도수분포표
count <- table(data$class)
count
2seater compact midsize minivan pickup subcompact
5 47 41 11 33 35
suv
62
# 백분율
prop.table(count)
2seater compact midsize minivan pickup subcompact
0.02136752 0.20085470 0.17521368 0.04700855 0.14102564 0.14957265
suv
0.26495726
geom_bar()
를
사용해야 한다.p1 <- ggplot(data, aes(x = class)) + # ggplot(데이터 프레임)NAgeom_bar() + # 막대 그래프 생성생성
labs(x = "Class", y = "Count") + # x축과 y축 label 변경 theme_bw()
p1
p1 + coord_flip() # 가로 형태의 막대 그래프
Caution!
가로 형태의 막대 그래프를 작성하기 위해서는
함수 coord_flip()
를 추가해야 한다.
Caution!
막대 그래프의 색깔 변경은 옵션
fill = 색깔
를 지정하면 된다.
counts <- table(data$class)
counts
2seater compact midsize minivan pickup subcompact
5 47 41 11 33 35
suv
62
df_counts <- data.frame(counts)
df_counts
Var1 Freq
1 2seater 5
2 compact 47
3 midsize 41
4 minivan 11
5 pickup 33
6 subcompact 35
7 suv 62
Caution!
데이터가 각 범주의 빈도로 주어진 경우, 막대
그래프를 작성하기 위해서는 함수 geom_bar()
에 옵션
stat = "identity"
을 추가하거나 함수
geom_col()
을 사용한다.
p2 + coord_flip() # 가로 형태의 막대 그래프
ggplot()
에서 옵션
fill = 범주가 입력된 열 이름
를 추가한 후 함수
coord_polar(theta = "y")
를 사용한다.df_prop <- df_counts %>%
mutate(prob = Freq/sum(Freq)) # 백분율 계산한 변수 추가
df_prop
Var1 Freq prob
1 2seater 5 0.02136752
2 compact 47 0.20085470
3 midsize 41 0.17521368
4 minivan 11 0.04700855
5 pickup 33 0.14102564
6 subcompact 35 0.14957265
7 suv 62 0.26495726
ggplot(df_prop, aes(x = "", # ggplot(데이터 프레임)NA= Freq, # 빈도가 입력된 열 이름이름
fill = Var1)) + # 범주가 입력된 열 이름 +
geom_bar(stat = "identity", # df_counts가 범주의 빈도로 주어진 데이터이기 때문NA= 1) +
labs(x = "", y = "", fill = "class") + # x축과 y축, fill label 변경 coord_polar(theta = "y") + # 파이 그래프NAgeom_text(aes(label = paste0(round(prob*100, 1), "%")),
position = position_stack(vjust = 0.5)) +
theme_bw()
Caution!
그래프에 라벨을 추가하기 위해서는 함수
geom_text()
를 사용할 수 있다. 함수
geom_text()
의 옵션 label
에는 라벨에 넣으려면
내용, 옵션 position
에는 라벨의 위치를 지정한다.
2seater compact midsize minivan pickup subcompact
5 47 41 11 33 35
suv
62
df_counts <- data.frame(counts)
df_counts
Var1 Freq
1 2seater 5
2 compact 47
3 midsize 41
4 minivan 11
5 pickup 33
6 subcompact 35
7 suv 62
ggDonut(df_counts, aes(donuts = Var1, count = Freq))
Caution!
도넛 그래프를 작성하기 위해서는 Package
ggiraphExtra
에 내장된 함수 ggDonut
를 사용할 수
있다.
2seater compact midsize minivan pickup subcompact
5 47 41 11 33 35
suv
62
# 백분율
prop <- round(prop.table(counts)*100, 1)
prop
2seater compact midsize minivan pickup subcompact
2.1 20.1 17.5 4.7 14.1 15.0
suv
26.5
Caution!
3D 파이 그래프를 작성하기 위해서는 Package
plotrix
에 내장된 함수 pie3D
를 사용할 수
있다.
table()
을 이용하여 나타낼 수
있다.
prop.table(도수분포표 또는 분할표)
을 이용한다.# 변수 class와 fl의 분할표table <- table(data$class, data$fl)
table
c d e p r
2seater 0 0 0 5 0
compact 0 1 0 21 25
midsize 0 0 0 15 26
minivan 0 0 1 0 10
pickup 0 0 3 0 30
subcompact 1 2 0 3 29
suv 0 2 4 8 48
fl
class c d e p r
2seater 0 0 0 5 0
compact 0 1 0 21 25
midsize 0 0 0 15 26
minivan 0 0 1 0 10
pickup 0 0 3 0 30
subcompact 1 2 0 3 29
suv 0 2 4 8 48
Caution!
함수 with()
와 함께 함수
table()
을 사용하면 변수 이름도 함께 출력된다.
# 백분율
prop.table(table)
c d e p
2seater 0.000000000 0.000000000 0.000000000 0.021367521
compact 0.000000000 0.004273504 0.000000000 0.089743590
midsize 0.000000000 0.000000000 0.000000000 0.064102564
minivan 0.000000000 0.000000000 0.004273504 0.000000000
pickup 0.000000000 0.000000000 0.012820513 0.000000000
subcompact 0.004273504 0.008547009 0.000000000 0.012820513
suv 0.000000000 0.008547009 0.017094017 0.034188034
r
2seater 0.000000000
compact 0.106837607
midsize 0.111111111
minivan 0.042735043
pickup 0.128205128
subcompact 0.123931624
suv 0.205128205
prop.table(table_with)
fl
class c d e p
2seater 0.000000000 0.000000000 0.000000000 0.021367521
compact 0.000000000 0.004273504 0.000000000 0.089743590
midsize 0.000000000 0.000000000 0.000000000 0.064102564
minivan 0.000000000 0.000000000 0.004273504 0.000000000
pickup 0.000000000 0.000000000 0.012820513 0.000000000
subcompact 0.004273504 0.008547009 0.000000000 0.012820513
suv 0.000000000 0.008547009 0.017094017 0.034188034
fl
class r
2seater 0.000000000
compact 0.106837607
midsize 0.111111111
minivan 0.042735043
pickup 0.128205128
subcompact 0.123931624
suv 0.205128205
geom_bar()
를 사용하면 된다.Result!
변수 “fl”의 빈도와 변수 “fl”내에서 변수
“class”의 빈도를 함께 나타낸다.
Caution!
옆으로 붙여 놓은 막대 그래프를 작성하기
위해서는 함수 geom_bar()
의 옵션
position = "dodge"
을 지정해야 한다.
Result!
변수 “fl”내에서 변수 “class”의 빈도를 나타낸다.
table <- table(data$class, data$fl)
table
c d e p r
2seater 0 0 0 5 0
compact 0 1 0 21 25
midsize 0 0 0 15 26
minivan 0 0 1 0 10
pickup 0 0 3 0 30
subcompact 1 2 0 3 29
suv 0 2 4 8 48
df_table <- data.frame(table)
df_table
Var1 Var2 Freq
1 2seater c 0
2 compact c 0
3 midsize c 0
4 minivan c 0
5 pickup c 0
6 subcompact c 1
7 suv c 0
8 2seater d 0
9 compact d 1
10 midsize d 0
11 minivan d 0
12 pickup d 0
13 subcompact d 2
14 suv d 2
15 2seater e 0
16 compact e 0
17 midsize e 0
18 minivan e 1
19 pickup e 3
20 subcompact e 0
21 suv e 4
22 2seater p 5
23 compact p 21
24 midsize p 15
25 minivan p 0
26 pickup p 0
27 subcompact p 3
28 suv p 8
29 2seater r 0
30 compact r 25
31 midsize r 26
32 minivan r 10
33 pickup r 30
34 subcompact r 29
35 suv r 48
ggplot(df_table, aes(x = Var2, y = Freq, fill = Var1)) + # Var2(fl), Var1(class)
geom_bar(stat = "identity") + # df_table이 각 범주 조합의 빈도로 주어진 데이터이기 때문NAgeom_text(aes(label = Freq),
position = position_stack(vjust = 0.5)) +
labs(x = "fl", y = "count", fill = "class") + # x축, y축, fill label 변경 theme_bw()
Caution!
그래프에 라벨을 추가하기 위해서는 함수
geom_text()
를 사용할 수 있다. 함수
geom_text()
의 옵션 label
에는 라벨에 넣으려면
내용, 옵션 position
에는 라벨의 위치를 지정한다.
Caution!
함수 geom_bar()
의 옵션
position = "fill"
을 지정하면, 변수 “fl” 내에서 변수
“class”의 상대적인 비율을 나타낼 수 있으며 막대의 높이는 “1”이 된다.
Caution!
함수 facet_wrap(~변수)
를 사용하면,
지정한 변수의 범주별로 분할하여 그래프를 나타낸다. 이 함수는 범주별
데이터의 분포를 비교하는 데 유용하다.
webr
에 내장된 함수 PieDonut()
를 사용할 수
있다.
PieDonut()
는 파이 그래프와 도넛 그래프를 합친
그래프를 생성하는 데 쌓아 올린 막대
그래프를 원 그래프로 나타냈다고 생각하면 된다.연속형 데이터란 측정된 데이터가 연속된 구간의 수치값을 가지는 것을 의미한다. 예를 들어, 수명 시간, 키, 몸무게 등이 있다.
데이터의 분포 형태
이다.stem()
으로 작성할 수 있다.stem(data$displ)
The decimal point is at the |
1 | 6666688888888888888999
2 | 0000000000000000000002222224444444444444
2 | 55555555555555555555777777778888888888
3 | 000000001111113333333334444
3 | 555556677788888888999
4 | 00000000000000022224
4 | 6666666666677777777777777777
5 | 002222233333344444444
5 | 67777777799
6 | 0122
6 | 5
7 | 0
geom_dotplot()
으로 작성할 수
있다.ggplot(data, aes(x = displ)) +
geom_dotplot() +
theme_bw()
geom_boxplot()
을
사용해야 한다.
bx <- ggplot(data, aes(x = "", y = displ)) +
geom_boxplot() +
labs(x = "") + # x축 label 변경
theme_bw()
bx
bx + coord_flip() # 가로 형태의 상자 그림NA
Caution!
가로 형태의 상자 그림을 작성하기 위해서는 함수
coord_flip()
를 추가해야 한다.
bx + geom_point(color = "red")
Caution!
상자 그림에 데이터의 위치를 점으로 함께
나타내기 위해 함수 geom_point()
를 사용할 수 있다.
bx + stat_summary(fun = "mean",
geom = "point", # 평균울 점으로 표시 color = "red", # 색깔 지정 shape = 3, # 점 모양 변경경
size = 4, # 크기
stroke = 2) # 굵기기
Caution!
상자 그림에 평균값의 위치를 나타내기 위해 함수
stat_summary()
를 사용할 수 있다.
geom_violin()
을
사용해야 한다.ggplot(data, aes(x = "", y = displ)) +
geom_violin() +
geom_boxplot(width = 0.07) + # 상자 그림도 함께 나타내기타내기
theme_bw()
ggplot(data, aes(x = "", y = displ)) +
geom_violin(trim = FALSE) +
geom_boxplot(width = 0.07) + # 상자 그림도 함께 나타내기타내기
theme_bw()
Caution!
함수 geom_violin()
에 옵션
trim = FALSE
를 지정하면 그래프의 양 끝부분을 다듬지
않는다.
geom_histogram()
을
사용해야 한다.ggplot(data, aes(x = displ)) +
geom_histogram(bins = 20) +
theme_bw()
Caution!
함수 geom_histogram()
에 옵션
bins
를 통해 구간의 개수를 지정할 수 있다.
ggplot(data, aes(x = displ)) +
geom_histogram(binwidth = 0.5) +
theme_bw()
Caution!
함수 geom_histogram()
에 옵션
binwidth
를 통해 구간의 폭을 지정할 수 있다.
geom_density()
를 사용해야 한다.ggplot(data, aes(x = displ)) +
geom_density(fill = "skyblue") +
theme_bw()
ggplot(data, aes(x = displ, y = stat(density))) +
geom_density(color = "blue") +
geom_histogram(fill = "skyblue", alpha = 0.4) +
theme_bw()
Caution!
히스토그램과 확률밀도함수 그래프를 같이
나타내기 위해서는 함수 ggplot()
에
y = stat(density)
를 지정해줘야 한다.
geom_point()
를 통해 작성할 수 있다.p1 <- ggplot(data, aes(x = cty, y = hwy)) +
geom_point() +
theme_bw()
p1
ggplot(data, aes(x = cty, y = hwy)) +
geom_point(shape = 21, # 점 모양
color = "blue", # 점 외곽선 색깔깔
fill = "skyblue", # 점 안 색깔
stroke = 1.5, # 점 외곽선 두께두께
size = 3) + # 점 크기
theme_bw()
Caution!
함수 geom_point()
의 다양한 옵션
지정을 통해 산점도에 변화를 줄 수 있다. 자세한 옵션은 여기를
참고한다.
geom_smooth()
에 선형회귀모형을
의미하는 옵션 method = "lm"
을 지정하면 된다.geom_smooth()
에
국소회귀곡선을 의미하는 옵션 method = "loess"
을 지정하면
된다.# 선형회귀모형p1 + geom_smooth(method = "lm")
# 국소회귀곡선곡선
p1 + geom_smooth(method = "loess")
# 선형회귀모형과 국소회귀곡선을 함께께
p1 +
geom_smooth(aes(color = "lm"), method = "lm") +
geom_smooth(aes(color = "loess"), method = "loess")
pacman::p_load("ggpubr") # For stat_cor()
p1 + geom_smooth(method = "lm") +
stat_cor(method = "pearson", # 상관분석 방법법
aes(label = paste(..r.label.., ..p.label.., sep = "~`,`~")), # r.label = R, rr.label = R^2, p.label = p-value
show.legend = FALSE)
Caution!
함수 stat_cor()
를 통해 두 변수
간의 상관계수와 \(p\)값을 계산할 수
있다. 자세한 옵션은 여기를
참고한다.
ggExtra
에 내장된 함수
ggMarginal()
은 산점도 그래프와 함께 주변 분포를 다양한
형태로 나타내는 데 유용한 함수이다.geom_bin2d()
를 통해 2D 히스토그램을 나타내는 것이다.ggplot(data, aes(x = cty, y = hwy)) +
geom_bin2d() +
theme_bw()
ggplot(data, aes(x = cty, y = hwy)) +
geom_bin2d() +
scale_fill_gradient(low = "skyblue", high = "red") +
theme_bw()
Caution!
함수 scale_fill_gradient()
을 통해
원하는 색깔을 지정할 수 있다.
geom_density_2d()
를 통해 작성할
수 있다.ggplot(data, aes(x = cty, y = hwy)) +
geom_density_2d() +
theme_bw()
Caution!
등고선 그래프는 3차원 자료를 2차원 공간에
표시한 것으로 확률밀도가 같은 영역을 선으로 연결하여 그린 그래프다. 각
등고선에 적절한 라벨이 붙어 있어야 확률밀도가 높은 지역과 낮은 지역을
구분할 수 있지만, 라벨을 일일이 확인하여 높이를 구분하는 작업은 번거롭고
부정확할 수 밖에 없다. 대안으로 제시되는 방법은 등고선의 높이를 색으로
구분하는 것이다. 시각적 요소 color = stat(level)
로 매핑하여
선의 색깔을 구분시킬수 있으며, 함수
scale_color_gradient()
를 이용하여 색깔의 변화를 조정할 수도
있다.
ggplot(data, aes(x = cty, y = hwy)) +
geom_density_2d(aes(color = stat(level))) +
scale_color_gradient(low = "blue", high = "red") +
theme_bw()
Caution!
등고선을 색으로 구분하는 것보다 높이가 같은
영역을 구분된 색으로 채우는 것이 더 효율적일 수 있다. 작성 방법은 함수
stat_density_2d()
를 사용하여 옵션
geom = "polygon"
을 지정하고, 시각적 요소
fill = stat(level)
을 매핑하는 것이다.
GGally
에 내장된 함수
ggpairs()
로 작성할 수 있다.pacman::p_load("GGally")
scat_df <- data %>%
select_if(is.numeric) # 수치형 변수만 선택택
scat_df
# A tibble: 234 x 5
displ year cyl cty hwy
<dbl> <int> <int> <int> <int>
1 1.8 1999 4 18 29
2 1.8 1999 4 21 29
3 2 2008 4 20 31
4 2 2008 4 21 30
5 2.8 1999 6 16 26
6 2.8 1999 6 18 26
7 3.1 2008 6 18 27
8 1.8 1999 4 18 26
9 1.8 1999 4 16 25
10 2 2008 4 20 28
# ... with 224 more rows
ggpairs(scat_df) +
theme_bw()
facet_wrap()
또는
facet_grid()
를 이용할 수 있다.# 변수 fl에 따른 변수 displ의 지터 그래프(함수 facet_wrap 이용)ggplot(data, aes(x = "", y = displ)) +
geom_jitter() +
facet_wrap(~fl, ncol = 1) +
theme_bw()
# 변수 fl에 따른 변수 displ의 지터 그래프(하나의 그래프로 작성)
ggplot(data, aes(x = fl, y = displ, color = fl)) +
geom_jitter() +
theme_bw()
# 변수 fl에 따른 변수 displ의 상자 그림(함수 facet_wrap 이용))
ggplot(data, aes(y = displ)) +
geom_boxplot() +
facet_wrap(~fl, ncol = 1) +
theme_bw()
# 변수 fl에 따른 변수 displ의 상자 그림(하나의 그래프로 작성)성)
ggplot(data, aes(x = fl, y = displ, fill = fl)) +
geom_boxplot(alpha = 0.3) +
theme_bw()
# 변수 fl에 따른 변수 displ의 상자 그림과 점 그래프그래프
ggplot(data, aes(x = fl, y = displ)) +
geom_dotplot(binaxis = "y", # 구간 설정 대상이 되는 축축
binwidth = 0.05, # 점 크기
stackdir = "center") + # 점을 쌓아 가는 방향
geom_boxplot() +
theme_bw()
# 변수 fl에 따른 변수 displ의 상자 그림과 지터 그래프프
ggplot(data, aes(x = fl, y = displ, color = fl)) +
geom_boxplot() +
geom_jitter() +
theme_bw()
# 변수 fl에 따른 변수 displ의 바이올린 그림(함수 facet_wrap 이용)용)
ggplot(data, aes(x = "", y = displ)) +
geom_violin(trim = FALSE) +
facet_wrap(~fl, ncol = 1) +
theme_bw()
# 변수 fl에 따른 변수 displ의 바이올린 그림(하나의 그래프로 작성)작성)
ggplot(data, aes(x = fl, y = displ, fill = fl)) +
geom_violin(trim = FALSE, alpha = 0.3) +
theme_bw()
# 변수 fl에 따른 변수 displ의 바이올린 그림과 점 그래프 그래프
ggplot(data, aes(x = fl, y = displ)) +
geom_dotplot(binaxis = "y", # 구간 설정 대상이 되는 축축
binwidth = 0.05, # 점 크기
stackdir = "center") + # 점을 쌓아 가는 방향
geom_violin(trim = FALSE) +
theme_bw()
# 변수 fl에 따른 변수 displ의 바이올린 그림과 지터 그래프래프
ggplot(data, aes(x = fl, y = displ, color = fl)) +
geom_violin(trim = FALSE) +
geom_jitter() +
theme_bw()
# 변수 fl에 따른 변수 displ의 히스토그램(함수 facet_wrap 이용))
ggplot(data, aes(x = displ)) +
geom_histogram() +
facet_wrap(~fl, ncol = 1) +
theme_bw()
# 변수 fl에 따른 변수 displ의 히스토그램(겹쳐서 작성)작성)
ggplot(data, aes(x = displ, fill = fl)) +
geom_histogram(alpha = 0.3) +
theme_bw()
# 변수 fl에 따른 변수 displ의 확률밀도함수(함수 facet_wrap 이용))
ggplot(data, aes(x = displ)) +
geom_density() +
facet_wrap(~fl, ncol = 1) +
theme_bw()
# 변수 fl에 따른 변수 displ의 확률밀도함수(겹쳐서 작성)작성)
ggplot(data, aes(x = displ, fill = fl)) +
geom_density(alpha = 0.3) +
theme_bw()
Text and figures are licensed under Creative Commons Attribution CC BY 4.0. The figures that have been reused from other sources don't fall under this license and can be recognized by a note in their caption: "Figure from ...".