091
[R] 자료구조(3): 매트릭스(Matrix) & 데이터프레임(Dataframe) 본문
(4) Matrix
- 같은 타입의 데이터를 2차원인 행렬로 배열한 구조로, 벡터에 차원(dim) 속성을 붙인것 과 같습니다. matrix(...)을 사용하여 선언하며, nrow,ncol,byrow와 같은 것을 이용해 내부 값의 배치를 바꿀 수 있습니다.
score <- matrix(c(90,85,69,78,
85,96,49,95,
90,80,70,60),
nrow=4,ncol=3)
score
# [,1] [,2] [,3]
#[1,] 90 85 90
#[2,] 85 96 80
#[3,] 69 49 70
#[4,] 78 95 60
rownames(score) #NULL
colnames(score) #NULL
rownames(score) <- c("John","Tom","Mark","Jane")
colnames(score) <- c("English","Math","Science")
rownames(score) #[1] "John" "Tom" "Mark" "Jane"
colnames(score) #[1] "English" "Math" "Science"
score
# English Math Science
#John 90 85 90
#Tom 85 96 80
#Mark 69 49 70
#Jane 78 95 60
-> score라는 matrix를 만들고 나서 출력해보면 내부값이 열이 우선적으로 채워집니다. 만약에 행을 우선으로 채우고싶다면, byrow=T라는 속성을 넣어주면 됩니다. matrix는 2차원이기 때문에 rownames, colnames에 <- 할당하여 채워줄 수 있습니다.
score["John","Math"] #[1] 85
score["Tom",c("Math","English")]
# Math English
# 96 85
score["Mark"] #[1] NA
score["Mark",]
#English Math Science
# 69 49 70
score["English"] #[1] NA
score[,"English"]
#John Tom Mark Jane
# 90 85 69 78
colnames(score)[2] #[1] "Math"
-> matrix에서는 값을 추출할 때 [행, 열]로 접근하여 추출합니다. 이후 설명할 데이터프레임과는 다르게 단일 행으로 접근 시에는 숫자로 접근하지 않는 이상 해당 값이 없는 NA가 출력되며, 숫자로 접근시에는 들어간 값들을 순서대로 인덱싱 되어 있는 경우에 출력됩니다. 없으면 마찬가지로 NA가 나옵니다.(즉, score[3]으로 접근 시에 [1] 69가 출력되지만, score["Mark"]로 접근시에는 [1] NA가 나옴, 물론 백터로 펼친 값 중에서도 없을 값인 score[13]으로 접근 시에는 [1] NA가 출력)
z <- matrix(1:20, nrow=4, ncol=5)
z
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 5 9 13 17
#[2,] 2 6 10 14 18
#[3,] 3 7 11 15 19
#[4,] 4 8 12 16 20
z.byrow <- matrix(1:20, nrow=4, ncol=5,byrow=T)
z.byrow
# [,1] [,2] [,3] [,4] [,5]
#[1,] 1 2 3 4 5
#[2,] 6 7 8 9 10
#[3,] 11 12 13 14 15
#[4,] 16 17 18 19 20
x <- c(1:4)
m1 <- cbind(x,z)
m1
# x
#[1,] 1 1 5 9 13 17
#[2,] 2 2 6 10 14 18
#[3,] 3 3 7 11 15 19
#[4,] 4 4 8 12 16 20
y <- c(1:5)
m2 <- rbind(y,z)
m2
# [,1] [,2] [,3] [,4] [,5]
# y 1 2 3 4 5
# 1 5 9 13 17
# 2 6 10 14 18
# 3 7 11 15 19
# 4 8 12 16 20
-> vector와 vector나 vector와 matrix를 연결할 때 cbind(...), rbind(...)를 사용합니다.
(5) Dataframe
- 행렬처럼 2차원이지만, 열마다 다른 타입을 허용하는 자료구조로, 실제 데이터 분석에서 많이 사용되는 구조입니다. data.frame(...)을 사용하여 선언합니다.
city <- c("Seoul","Tokyo","Washington")
rank <- c(1,3,2)
city.info <- data.frame(city,rank)
city.info
# city rank
# 1 Seoul 1
# 2 Tokyo 3
# 3 Washington 2
-> 다른 타입의 두 벡터를 데이터 프레임으로 열 병합을 해줍니다.
city.info$rank #[1] 1 3 2
city.info["rank"] #열 추출(1)
# rank
#1 1
#2 3
#3 2
city.info[1] #열 추출(2)
# city
#1 Seoul
#2 Tokyo
#3 Washington
city.info[,1] #열 추출(3)
#[1] "Seoul" "Tokyo" "Washington"
city.info[,"city"] #열 추출(4)
#[1] "Seoul" "Tokyo" "Washington"
city.info[1,]#행 추출
# city rank
#1 Seoul 1
city.info[1,1] #[1] "Seoul"
-> 데이터프레임도 값을 추출하는 방식이 여러가지인데 만약에 단일 행으로 이름으로 접근할 경우에는 rank처럼 행 번호까지 같이 나오며, [] 단일 추출시에도 그렇게 나오지만, [,1] 열임을 확실히 명시해주면 내부값만 추출됩니다. 행 추출을 원하면 무조건 콤마를 작성해줘야하며, 행렬이기 때문에 인덱스 접근도 물론 가능합니다.
Q. matrix는 없는 행렬 번호 접근 시에 error가 발생하는데 dataframe은 왜 NULL이 출력되나요?
A. matrix는 내부적으로 원자적 벡터에 차원 속성을 부여한 엄격한 격자 구조로, 벗어난 공간은 아예 존재하지 않는것으로 취급하기 때문에 error가 발생하고, 데이터프레임은 길이가 같은 벡터들을 모아둔 리스트 구조로 구현되어있기 때문에, 단일 대괄호로 인덱스에 접근할 때는 내용물을 직접 꺼내지 않기 때문에 해당 이름을 가진 리스트가 없다는 의미로 에러가 아닌 NULL이 출력됩니다. 만약 이중 대괄호로 내용물을 꺼내려고 한다면 리스트나 데이터프레임도 error가 발생합니다.
[벡터]------------------
d[100] #[1] NA
[매트릭스]---------------
score[6,] #error
score[6,1] #error
score[55] #[1] NA, 매트릭스를 단일행으로 접근하는 것은 벡터를 일자로 해두고 접근하는 것과 유사
[리스트]----------------
my.info[100]
#$<NA>
#NULL
my.info[[100]] #error
[데이터프레임]---------------
city.info[4,]
# city rank
#NA <NA> NA
city.info[4,1] #[1] NA
city.info[[4,1]] #error
-> 문자열의 경우 실제 값이 NA이 일수도 있으므로 문자열 열(city.info의 city 열)의 경우 <NA>의 형식으로 작성됩니다.
-> 있는 값에 대한 데이터프레임 값을 추출할 때는 사실 []와 [[]]의 차이는 느낄 수가 없습니다.(출력값과 출력타입이 동일) 하지만, 값이 존재하지 않는 위의 경우에서는 대괄호를 두개 사용하면, 융통성 없이 단 하나의 값에 접근하기 때문에 방이 없는 경우에는 error가 발생하는 것입니다.
- 매트릭스와 데이터프레임 모두 사용 가능한 공통함수입니다. 이 함수들을 설명할 때는 R 내부에 있는 매트릭스 state.x77과 데이터프레임 iris를 사용합니다.
| 함수 | 기능 |
| dim() | 데이터의 차원(행과 열)을 한번에 출력 |
| ncol() | 데이터의 열의 개수를 출력 |
| nrow() | 데이터의 행의 개수를 출력 |
| colnames() | 데이터의 열의 이름을 출력 |
| rownames() | 데이터의 행의 이름을 출력 |
| head() | 데이터의 위쪽 6행을 출력 |
| tail() | 데이터의 아래쪽 6행을 출력 |
| str() | 구조 출력(데이터 종류, 행/열 크기, 데이터 타입 등) |
| subset() | 원하는 조건의 데이터를 필터링 |
| t() | 전치(Transpose)의 약자로, 행렬을 뒤바꿈 |
| colSums()/rowSums() | 각 열/행의 합계 |
| colMeans()/rowMeans() | 각 열/행의 평균 |
dim(state.x77) #[1] 50 8
nrow(state.x77) #[1] 50
ncol(state.x77) #[1] 8
colnames(state.x77) #[1] "Population" "Income" "Illiteracy" "Life Exp" "Murder" "HS Grad" "Frost" "Area"
head(state.x77)
# Population Income Illiteracy Life Exp Murder HS Grad Frost Area
#Alabama 3615 3624 2.1 69.05 15.1 41.3 20 50708
#Alaska 365 6315 1.5 69.31 11.3 66.7 152 566432
#Arizona 2212 4530 1.8 70.55 7.8 58.1 15 113417
#Arkansas 2110 3378 1.9 70.66 10.1 39.9 65 51945
#California 21198 5114 1.1 71.71 10.3 62.6 20 156361
#Colorado 2541 4884 0.7 72.06 6.8 63.9 166 103766
tail(state.x77)
# Population Income Illiteracy Life Exp Murder HS Grad Frost Area
#Vermont 472 3907 0.6 71.64 5.5 57.1 168 9267
#Virginia 4981 4701 1.4 70.08 9.5 47.8 85 39780
#Washington 3559 4864 0.6 71.72 4.3 63.5 32 66570
#West Virginia 1799 3617 1.4 69.48 6.7 41.6 100 24070
#Wisconsin 4589 4468 0.7 72.48 3.0 54.5 149 54464
#Wyoming 376 4566 0.6 70.29 6.9 62.9 173 97203
-> state.x77은 미국의 50개 주에 대한 사회•경제적 통계 지표를 모아놓은 데이터로, matrix 자료구조입니다.
dim(iris) #[1] 150 5
nrow(iris) #[1] 150
ncol(iris) #[1] 5
colnames(iris) #[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
head(iris)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 5.1 3.5 1.4 0.2 setosa
#2 4.9 3.0 1.4 0.2 setosa
#3 4.7 3.2 1.3 0.2 setosa
#4 4.6 3.1 1.5 0.2 setosa
#5 5.0 3.6 1.4 0.2 setosa
#6 5.4 3.9 1.7 0.4 setosa
tail(iris)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#145 6.7 3.3 5.7 2.5 virginica
#146 6.7 3.0 5.2 2.3 virginica
#147 6.3 2.5 5.0 1.9 virginica
#148 6.5 3.0 5.2 2.0 virginica
#149 6.2 3.4 5.4 2.3 virginica
#150 5.9 3.0 5.1 1.8 virginica
-> iris는 붓꽃이라는 식물의 3가지 품종별로 꽃잎(Petal)과 꽃받침(Sepal)의 길이를 측정한 데이터로, dataframe 자료구조입니다.
str(iris)
#'data.frame': 150 obs. of 5 variables:
#$ Sepal.Length: num 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
#$ Sepal.Width : num 3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
#$ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
#$ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
#$ Species : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
levels(iris[,5]) #[1] "setosa" "versicolor" "virginica"
class(iris[,5]) #[1] "factor"
table(iris[,"Species"])
# setosa versicolor virginica
# 50 50 50
names <- c("Tom","Jane","Nick")
age <- c(20,23,26)
gender <- c("M","F","M")
height <- c(180,160,175)
student <- c(T,T,F)
human <- data.frame(names,age,gender,height,student)
human
# names age gender height student
# 1 Tom 20 M 180 TRUE
# 2 Jane 23 F 160 TRUE
# 3 Nick 26 M 175 FALSE
str(human)
# 'data.frame': 3 obs. of 5 variables:
# $ names : chr "Tom" "Jane" "Nick"
# $ age : num 20 23 26
# $ gender : chr "M" "F" "M"
# $ height : num 180 160 175
# $ student: logi TRUE TRUE FALSE
mean(human$age) #[1] 23
mean(human$height) #[1] 171.6667
colnames(human)[-4] #[1] "names" "age" "gender" "student"
colnames(human[,-4]) #[1] "names" "age" "gender" "student"
table(human$gender)
# F M
# 1 2
-> str에서 각각 chr, num, logi 자료형을 가진다고 출력됩니다.
class(state.x77) #[1] "matrix" "array"
is.matrix(state.x77) #[1] TRUE
is.data.frame(state.x77) #[1] FALSE
str(state.x77)
#num [1:50, 1:8] 3615 365 2212 2110 21198 ...
#- attr(*, "dimnames")=List of 2
#..$ : chr [1:50] "Alabama" "Alaska" "Arizona" "Arkansas" ...
#..$ : chr [1:8] "Population" "Income" "Illiteracy" "Life Exp" ...
st <- as.data.frame(state.x77[1:2,1:2])
head(st)
# Population Income
#Alabama 3615 3624
#Alaska 365 6315
class(st) #[1] "data.frame"
iris.m <- as.matrix(iris[1:2,1:2])
head(iris.m)
# Sepal.Length Sepal.Width
#1 5.1 3.5
#2 4.9 3.0
class(iris.m) #[1] "matrix" "array"
-> state.x77에서는 matrix와 array가 같이 뜨는 이유는 행렬은 배열의 한 종류이기 때문에 동시에 뜨는 것입니다.
-> is.자료형으로 해당 자료형인지 아닌지에 대한 여부를 알 수 있고, as.자료형으로 해당 자료형으로 변환을 시도할 수 있습니다.
IR.1 <- subset(iris,Species=="setosa")
head(IR.1)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#1 5.1 3.5 1.4 0.2 setosa
#2 4.9 3.0 1.4 0.2 setosa
#3 4.7 3.2 1.3 0.2 setosa
#4 4.6 3.1 1.5 0.2 setosa
#5 5.0 3.6 1.4 0.2 setosa
#6 5.4 3.9 1.7 0.4 setosa
IR.2 <- subset(iris, Sepal.Length>5.0&Sepal.Width>4.0)
tail(IR.2)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#16 5.7 4.4 1.5 0.4 setosa
#33 5.2 4.1 1.5 0.1 setosa
#34 5.5 4.2 1.4 0.2 setosa
-> subset(데이터, 조건) 함수를 사용해 원하는 값을 추출해낼 수 있습니다.
IR.1 <- subset(airjsm, wind>10)
IR.1
# [1] temp wind
# <0 rows> (or 0-length row.names)
-> subset으로 지정한 조건에 해당하는 열이 없을 때 나오는 출력값 입니다.
alpha <- matrix(c('A','B','A','B'),nrow=2,ncol=2,byrow=T)
rownames(alpha) <- c('C1','D1')
colnames(alpha) <- c('A1','B1')
alpha
# A1 B1
# C1 "A" "B"
# D1 "A" "B"
alpha1 <- as.data.frame(alpha)
alpha1
# A1 B1
# C1 A B
# D1 A B
A0 <- subset(alpha, alpha[,'B1']=="B")
A0
# A1 B1
# C1 "A" "B"
# D1 "A" "B"
#data.frame에서만 열이름을 변수처럼 사용 가능
A1 <- subset(alpha1,B1=="B")
A1
# A1 B1
# C1 A B
# D1 A B
-> subset에서 조건 부분에 변수처럼 사용하는 것은 데이터프레임만 가능합니다. matrix에서는 추출하듯이 작성해야합니다.
z <- matrix(1:20,nrow=4,ncol=5)
z
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 5 9 13 17
# [2,] 2 6 10 14 18
# [3,] 3 7 11 15 19
# [4,] 4 8 12 16 20
t(z)
# [,1] [,2] [,3] [,4]
# [1,] 1 2 3 4
# [2,] 5 6 7 8
# [3,] 9 10 11 12
# [4,] 13 14 15 16
# [5,] 17 18 19 20
-> t() 함수를 통해 행렬을 뒤바꿀 수 있습니다.
colSums(iris[,-5])
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# 876.5 458.6 563.7 179.9
colMeans(iris[,-5])
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# 5.843333 3.057333 3.758000 1.199333
rowSums(iris[,-5])
#[1] 10.2 9.5 9.4 9.4 10.2 11.4 9.7 10.1 8.9 9.6 10.8 10.0 9.3 8.5 ...
rowMeans(iris[,-5])
#[1] 2.550 2.375 2.350 2.350 2.550 2.850 2.425 2.525 2.225 2.400 2.700...
-> 열에 관련된 함수는 열이름과 함께 출력되며, 행과 관련된 함수는 벡터처럼 쭉 출력됩니다.
score1 <- matrix(c(2,2,2,4,4,4),nrow=2,ncol=3,byrow=T)
score1
# [,1] [,2] [,3]
# [1,] 2 2 2
# [2,] 4 4 4
colSums(score1) #[1] 6 6 6
colMeans(score1) #[1] 3 3 3
rowSums(score1) #[1] 6 12
rowMeans(score1) #[1] 2 4
-> 만약 열도 특별한 이름이 없다면 위의 벡터처럼 출력됩니다. 만약 state.x77처럼 행에 이름이 있는 경우에는 위의 Sepal.Length처럼 각각 출력됩니다. 즉, 벡터처럼 출력됩니다.
'Programming Language > R' 카테고리의 다른 글
| [R] 기초문법(조건문, 반복문, 함수) (0) | 2026.04.06 |
|---|---|
| [R] 파일 데이터 읽기/쓰기 (0) | 2026.04.06 |
| [R] 자료구조(2): 리스트(List) & 팩터(Factor) (0) | 2026.04.01 |
| [R] 자료구조(1): 벡터(Vector) (0) | 2026.04.01 |
| [R] 기초문법(연산자, 변수, 기본 자료형) (0) | 2026.03.29 |
