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, ..등)으로 이루어진 자료일 경우에 유용하다.
수치형 벡터의 연산
기본적으로 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(행렬, 행/열방향, 적용할 함수).