x =seq(from =1, length =100, by =2) ;length(x) # x의 길이
[1] 100
head(x) # x의 최초 6개 성분만 열람
[1] 1 3 5 7 9 11
summary(x) # x의 성분들에 대한 기초통계 결과
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.0 50.5 100.0 100.0 149.5 199.0
sum(x) # x의 성분들의 합
[1] 10000
mean(x) # x의 성분들의 평균
[1] 100
var(x) # x의 성분들의 표본분산(편차제곱을 n-1로 나눔)
[1] 3366.667
c(1, 5, 19, 2, 1, 2, 2, 8)에 대하여 min(x), max(x), order(x), factor(x), table(x)… 등도 각자 해 보길 바란다. factor(x)와 table(x)는 x가 연속형 실수가 아닌 이산형(문자열형, 혹은 1, 2, 3, ..등)으로 이루어진 자료일 경우에 유용하다.
2.1.3 수치형 벡터의 연산
기본적으로 R은 열벡터(column vector)에 매우 친화적이다. R에서 벡터는 열벡터로 인식된다. 벡터가 화면에 가로로 나열되는 건 경제성을 위해서이다. 스칼라값도 R 내부적으로는 길이 1짜리 벡터로 취급된다.
R은 벡터 단위의 연산을 제공한다. 스칼라 곱은 당연히 되며, element-wise operation 또한 가능하다. element-wise operation은 행렬끼리의 연산에서도 지원된다. R의 좋은 기능 중 하나다.
a = pi/4tan(a)
[1] 1
b =c(pi/3, pi/4, pi/6) sin(b) # element-wise operation
[1] 0.8660254 0.7071068 0.5000000
exp(c(-1, 0, 1))
[1] 0.3678794 1.0000000 2.7182818
d =exp(c(-1, 0, 1)) b + d # element-wise operation
[1] 1.415077 1.785398 3.241881
b - d # element-wise operation
[1] 0.6793181 -0.2146018 -2.1946831
x =c(1, 2, 3) ; y =c(1, 2, 3) x -1
[1] 0 1 2
2* x
[1] 2 4 6
x * y # element-wise operation
[1] 1 4 9
sum(x * y) # inner product of x and y
[1] 14
x / y # element-wise operation
[1] 1 1 1
x - 1은 왜 가능할까? 길이가 다른 두 벡터가 만나면 짧은 벡터가 알아서 복제된다. 다만, 길이들이 서로 약수/배수의 관계에 있어야 warning이 뜨지 않는다.
x =c(1, 2, 3, 4, 5) x -c(1,2) ; # warning. 실제로는 c(1, 2, 3, 4, 5) - c(1, 2, 1, 2, 1) 계산
Warning in x - c(1, 2): longer object length is not a multiple of shorter
object length
[1] 0 0 2 2 4
x -1# 실제로는 c(1, 2, 3, 4, 5) - c(1, 1, 1, 1, 1) 계산
[1] 0 1 2 3 4
한편, 위에서 보았듯 *은 기본적으로 성분별 곱셈 연산자이며 이는 행렬에서도 똑같이 취급된다. 행렬의 곱셈은 연산자 %*%로 한다.
V1 V2 V3 V4
Min. : 1 Min. : 2 Min. : 3 Min. : 4
1st Qu.:15 1st Qu.:16 1st Qu.:17 1st Qu.:18
Median :29 Median :30 Median :31 Median :32
Mean :29 Mean :30 Mean :31 Mean :32
3rd Qu.:43 3rd Qu.:44 3rd Qu.:45 3rd Qu.:46
Max. :57 Max. :58 Max. :59 Max. :60
a =matrix(1:4, nrow =2, byrow = T) b = ax =c(1, 1)a %*% b
[,1] [,2]
[1,] 7 10
[2,] 15 22
a %*% x
[,1]
[1,] 3
[2,] 7
y =matrix(c(1,2), nrow =1)## a와 y의 행렬곱도 해 보라. 계산이 잘 정의되지 않는다. 왜?dim(y)
[1] 1 2
z = a[1, ] a %*% z
[,1]
[1,] 5
[2,] 11
dim(z)
NULL
위 계산에서 x는 길이 2짜리 벡터이므로 자동으로 열벡터로 취급되어 a %*% x가 잘 정의된다. y는 1 by 2 matrix이므로 a %*% y가 잘 정의되지 않는다. y가 1 by 2 matrix임은 dim(y)를 통해 확인할 수 있다. z는 명령어로 보건대 1 by 2 matrix같은데 a %*% z는 또 잘 계산된다. dim(z)가 NULL값을 반환하는 것으로 보아 z는 벡터임을 알 수 있다. 어떤 알고리즘 때문인지, 저렇게 추출한 z는 벡터 상태가 되었다.
R은 고급 행렬 연산도 모두 지원한다.
a =matrix(1:4, nrow =2, byrow = T) t(a) # transpose of a
[,1] [,2]
[1,] 1 3
[2,] 2 4
solve(a) # inverse of a
[,1] [,2]
[1,] -2.0 1.0
[2,] 1.5 -0.5
det(a) # determinant of a
[1] -2
diag(a) # diagonal elements of a, if a is a matrix
행별/열별 평균이나 합은 rowMeans(), colMeans(), rowSums(), colSums()를 사용할 수 있다. 일반적으로 R에서는 행렬에서 행/열 단위로 임의의 함수를 적용한 결과를 한꺼번에 얻을 수 있는 함수 apply()가 있다. apply의 사용법은 apply(행렬, 행/열방향, 적용할 함수).