참고도서: R 통계 프로그래밍의 이해 - 차영준, 박진표 (자유아카데미) 5장
www.yes24.com/Product/Goods/68712840
R 통계 프로그래밍의 이해
'최근에 빅데이터와 관련된 용어들이 많이 사용되고 있다. 인공지능, 머신러닝, 데이터 과학, 데이터 과학자, 4차 산업혁명 등과 같은 단어들을 많이 접하게 된다. 이처럼 많은 사람들이 빅데이
www.yes24.com
> #### 5.1 apply() 함수 ####
>
> #행렬에 행 방향으로 apply() 함수 적용
> mData <- matrix(1:10, ncol=2) ## matrix() 함수 이용하여 행렬 데이터 생성
> mData
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
> apply(mData, 1, mean) ## 행렬 또는 데이터 프레임 객체를 평균 함수를 지정하여 행 방향(1)에 적용
[1] 3.5 4.5 5.5 6.5 7.5
> rowMeans(mData) ## 행의 평균을 구하는 함수
[1] 3.5 4.5 5.5 6.5 7.5
>
> #행렬에 열 방향으로 apply() 함수 적용
> apply(mData, 2, mean) ## 행렬 또는 데이터 프레임 객체를 평균 함수를 지정하여 열 방향(2)에 적용
[1] 3 8
> colMeans(mData) ## 열의 평균을 구하는 함수
[1] 3 8
>
> #Using.R::kid.weights의 apply() 함수 적용
> install.packages("UsingR") ## kid.weights 데이터 세트를 실행하기 위해 UsingR 패키지 필요
> library(UsingR)
>
> head(kid.weights[, 1:3]) ## kid.weights 데이터 세트의 첫번째부터 세번째 열까지의 첫 6행 출력
age weight height
1 58 38 38
2 103 87 43
3 87 50 48
4 138 98 61
5 82 47 47
6 52 30 24
> str(kid.weights[, 1:3]) ## 데이터 구조 확인
'data.frame': 250 obs. of 3 variables:
$ age : num 58 103 87 138 82 52 28 79 107 45 ...
$ weight: num 38 87 50 98 47 30 24 45 144 24 ...
$ height: num 38 43 48 61 47 24 29 48 59 24 ...
>
> apply(kid.weights[, 1:3], 2, mean) ## 열 방향으로 평균(mean) 함수 적용(apply)
age weight height
47.948 38.384 36.524
> is.vector(apply(kid.weights[, 1:3], 2, mean)) ## 위 계산 결과가 벡터인지 확인
[1] TRUE
> colMeans(kid.weights[, 1:3])
age weight height
47.948 38.384 36.524
>
> apply(kid.weights[, 1:3], 2, summary)
## summary() 함수 : 수치형 벡터에 적용할 때 요약통계량을 출력
age weight height
Min. 3.000 10.000 12.000
1st Qu. 12.250 22.000 28.000
Median 39.000 32.000 36.000
Mean 47.948 38.384 36.524
3rd Qu. 69.750 45.000 43.000
Max. 144.000 150.000 67.000
> is.matrix(apply(kid.weights[, 1:3], 2, summary)) ## 위 계산 결과가 행렬인지 확인
[1] TRUE
>
>
> #### 5.2 lapply 함수 - list.apply ####
> #벡터인 경우 lapply() 적용
> x <- 1:3
> mean <- mean(x)
> sd <- sd(x) ## sd: 표준편차 계산
> z <- lapply(x, function(x){(x - mean) /sd })
## 변수를 표준화하는 함수을 생성하여 그 결과를 리스트로 반환
> z
[[1]]
[1] -1
[[2]]
[1] 0
[[3]]
[1] 1
>
> #리스트인 경우 lapply() 적용
> xyz <- list(x=1:3, y=10*1:3, z=100*1:3) ## 리스트 생성
> xyz
$x
[1] 1 2 3
$y
[1] 10 20 30
$z
[1] 100 200 300
> lData <- lapply(xyz, mean) ## 리스트의 평균을 계산하여 리스트(l)로 적용(apply)
> lData
$x
[1] 2
$y
[1] 20
$z
[1] 200
> # 자체예제
> loona <- list("1/3"=c(1019, 1115, 0818, 1111, 1209), OEC=c(0210, 0613, 0604), yyxy=c(0524, 1020, 1119, 1113))
> loona
$`1/3`
[1] 1019 1115 818 1111 1209
$OEC
[1] 210 613 604
$yyxy
[1] 524 1020 1119 1113
> loonaData <- lapply(loona, sum)
> loonaData ## 자체응용: 변수를 c() 함수로 묶은 리스트의 합계를 계산하여 리스트로 적용
$`1/3`
[1] 5272
$OEC
[1] 1427
$yyxy
[1] 3776
>
> #데이터 프레임인 경우 lapply() 함수 적용
> lapply(kid.weights[, 1:3], mean) ## 데이터 프레임의 평균을 계산하여 리스트로 적용
$age
[1] 47.948
$weight
[1] 38.384
$height
[1] 36.524
> lapply(kid.weights[, 1:3], summary)
$age
Min. 1st Qu. Median Mean 3rd Qu. Max.
3.00 12.25 39.00 47.95 69.75 144.00
$weight
Min. 1st Qu. Median Mean 3rd Qu. Max.
10.00 22.00 32.00 38.38 45.00 150.00
$height
Min. 1st Qu. Median Mean 3rd Qu. Max.
12.00 28.00 36.00 36.52 43.00 67.00
>
> #unlist() 함수를 이용하여 벡터로 변환
> is.list(lapply(kid.weights[, 1:3], mean)) ## 해당 식이 리스트인지 확인
[1] TRUE
> unlist(lapply(kid.weights[, 1:3], mean)) ## unlist() 함수를 이용하여 리스트를 벡터로 변환
age weight height
47.948 38.384 36.524
> is.vector(lapply(kid.weights[, 1:3], mean)) ## 해당 식이 벡터인지 확인
[1] TRUE
>
>
> #### 5.3 sapply() 함수 ####
> #벡터인 경우 sapply() 함수 적용
> x <- 1:3
> mean <- mean(x)
> sd <- sd(x) ## 표준편차 계산
> zS <- sapply(x, function(x) {(x-mean)/sd})
## 변수를 표준화하는 함수을 생성하여 그 결과를 벡터 또는 행렬로 반환
> zS
[1] -1 0 1
> is.vector(zS) ## 벡터인지 확인
[1] TRUE
>
> #리스트인 경우 sapply() 함수 적용
> abc <- list(a=1:3, b=10*1:3, c=100*1:3) ## 리스트 생성
> sData <- sapply(abc, mean) ## 리스트의 평균을 계산하여 벡터로 적용
> sData
a b c
2 20 200
> is.vector(sData) ## 벡터인지 확인
[1] TRUE
>
> #데이터 프레임 UsingR::kid.weights인 경우 sapply() 함수 적용
> install.packages("UsingR")
> library(UsingR)
>
> sapply(kid.weights[, 1:3], mean) ## kid.weights의 1~3열을 평균으로 계산하여 벡터로 출력
age weight height
47.948 38.384 36.524
> is.vector(sapply(kid.weights[, 1:3], mean)) ## 벡터인지 확인
[1] TRUE
>
> sapply(kid.weights[, 1:3], summary) ## 요약통계량 계산하여 행렬로 출력
age weight height
Min. 3.000 10.000 12.000
1st Qu. 12.250 22.000 28.000
Median 39.000 32.000 36.000
Mean 47.948 38.384 36.524
3rd Qu. 69.750 45.000 43.000
Max. 144.000 150.000 67.000
> is.matrix(sapply(kid.weights[, 1:3], summary)) ## 행렬인지 확인
[1] TRUE
>
>
> #### 5.4 tapply() 함수 ####
>
> #tapply() 함수를 이용한 index 별로 합 계산
> set.seed(81576) ## set.seed() 함수: 동일한 표본을 추출하기 위해 사용
> x <- sample(1:10, 6, replace = TRUE) ## 복원추출로 1부터 10까지 6개의 난수 추출
> x
[1] 4 3 5 8 8 5
>
> index <- factor(rep(1:2, each=3)) ## rep() 함수 2.2.4장 참고, 1부터 2까지 개별 값을 3번 반복
> index ## 팩터 출력
[1] 1 1 1 2 2 2
Levels: 1 2
>
> tapply(x, index, sum)
## index별로 합 계산 : x 값을 index == 1끼리, index == 2끼리 합(sum)하여 계산
1 2
12 21
>
> #tapply() 함수 UsingR::reaction.time 데이터 적용
> reaction.time2 <- within(reaction.time, {
+ control <- factor(control, labels=c("notUsing", "using"))
+ })
## control 변수에 "notUsing", "Using"이라는 이름을 붙임
> head(reaction.time2)
age gender control time
1 16-24 F using 1.360075
2 16-24 M using 1.467939
3 16-24 M using 1.512036
4 16-24 F using 1.390647
5 16-24 M using 1.384208
6 16-24 M notUsing 1.393875
>
> tapply(reaction.time2$time, reaction.time2$control, mean)
## time 변수의 평균(mean)을 control 별로 출력
notUsing using
1.389613 1.445571
> tapply(reaction.time2$time, reaction.time2$age, mean)
## time 변수의 평균을 age 별로 출력
16-24 25+
1.382586 1.449084
> tapply(reaction.time2$time, reaction.time2$gender, mean)
## time 변수의 평균을 gender 별로 출력
F M
1.441481 1.412356
>
>
> #### 5.5 mapply() 함수 - multiple.apply ####
>
> #mapply() 함수 활용
> mapply(seq, 1:5, 5:1) ## seq() 함수 2.2.3장 참고, 시작값부터 종료값까지 증가하는 등차수열 생성
[[1]]
[1] 1 2 3 4 5
[[2]]
[1] 2 3 4
[[3]]
[1] 3
[[4]]
[1] 4 3 2
[[5]]
[1] 5 4 3 2 1
> ## 위 수식 첫번째[[1]]는 1부터 5까지, 두번째[[2]]는 2부터 4까지, ... 마지막 다섯번째[[5]]는 5부터 1까지 출력
> is.list(mapply(seq, 1:5, 5:1)) ## 이 함수의 결과가 리스트인지 확인
[1] TRUE
>
> mapply(seq, 10:12, 30:28, 6) ## (자체응용) seq() 함수의 인수인 증분 값(by)을 넣은 등차수열 생성
[[1]]
[1] 10 16 22 28
[[2]]
[1] 11 17 23 29
[[3]]
[1] 12 18 24
> ## 첫번째는 10부터 30까지 6씩 증가(10,16,22,28)하는 등차수열을, 두번째는 11부터 29까지 6씩 증가(11,17,23,29)
> ## 하는 등차수열을, 세번째는 12부터 28까지 6씩 증가(12, 18, 24)하는 등차수열을 생성
>
> #mapply() 함수를 이용한 행렬 생성
> M <- matrix(c(rep(1, 3), rep(2, 3), rep(3, 3)), nrow=3) ## 1을 세 번 반복, 2를 세 번 반복, 3을 세 번 반복하고
> M ## 행의 수가 3개인 행렬 생성
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3
> mData <- mapply(rep, 1:3, c(3,3,3)) ## mapply() 함수를 이용하여 위와 똑같은 행렬 생성
> mData
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 1 2 3
[3,] 1 2 3
>
> #mapply() 함수를 이용한 난수발생
> runif(1, 0, 1) ## 난수 1개를 발생시키는데, 이는 최솟값 0, 최댓값 1인 균등분포를 따름
[1] 0.9812331
> runif(2, 0, 10) ## 난수 2개를 발생시키는데, 이는 최솟값 0, 최댓값 10인 균등분포를 따름
[1] 8.095492 8.535420
> runif(3, 0, 100) ## 난수 3개를 발생시키는데, 이는 최솟값 0, 최댓값 100인 균등분포를 따름
[1] 73.33537 71.82356 93.84858
>
> size <- c(1, 2, 3)
> min <- c(0, 0, 0)
> max <- c(1, 10, 100)
> mapply(runif, size, min, max) ## mapply() 함수를 이용하여 위와 같은 방식으로 난수를 발생시킴
[[1]]
[1] 0.9774314
[[2]]
[1] 1.501888 9.451198
[[3]]
[1] 71.91664 50.92009 44.05505
> ## 그리고 이 결과값은 리스트로 출력됨.
>
> #참고: 균등분포를 따르는 runif(난수, 최솟값, 최댓값) 함수
> # vs 정규분포를 따르는 rnorm(난수, 평균, 분산) 함수
> rnorm(1, 0, 1) ## 난수 1개를 발생시키는데, 이는 평균이 0이고 분산이 1인 정규분포를 따름
[1] -1.039073
> rnorm(2, 70, 5) ## 평균이 70이고 분산이 5인 정규분포를 따르는 난수 2개 발생
[1] 64.78700 77.99214
> set.seed(2418) ## 다음 식에서 발생되는 난수를 고정시킴
> rnorm(3, -15, 3) ## 평균이 -15이고 분산이 3인 정규분포를 따르는 난수 3개 발생
[1] -14.95596 -17.70777 -13.02290
>
> size <- c(1, 2, 3)
> avg <- c(0, 70, -15)
> var <- c(1, 5, 3)
> mapply(rnorm, size, avg, var)
[[1]]
[1] -0.3528121
[[2]]
[1] 75.04669 67.02967
[[3]]
[1] -18.44428 -13.13279 -15.90950
'데이터 [Data] > R' 카테고리의 다른 글
R Graphics 2: 그래프유형, 색상, 낮은 수준의 그래프함수 (0) | 2021.06.02 |
---|---|
R Graphics 1: plot(), attach(), with() 함수, 제목, 축 이름, 점(pch) (0) | 2021.06.01 |
R 제어문: 조건문, 반복문 (0) | 2021.04.30 |
R 데이터 가공: 결측값 처리, 그룹별 요약통계량 계산, 변환 (0) | 2021.04.29 |
R 데이터 가공: 정렬, 결합 및 분리 (0) | 2021.04.28 |
댓글