24 . 자료구조

R의 가장 강력한 기능중 하나는 표형식 데이터를 다룰 수 있는 능력이다 - 이미 스프레드쉬트나 CSV 파일을 갖고 있을 수 있다. data/ 디렉토리에 feline-data.csv 파일을 생성하면서 학습을 시작해 보자:

cats <- data.frame(coat = c("calico", "black", "tabby"), 
                    weight = c(2.1, 5.0,3.2), 
                    likes_string = c(1, 0, 1))
write.csv(x = cats, file = "data/feline-data.csv", row.names = FALSE)

새로 생성한 feline-data.csv 파일 내부는 다음과 같다:

coat,weight,likes_string
calico,2.1,1
black,5.0,0
tabby,3.2,1

꿀팁: R에서 텍스트 파일 편집

대안으로, data/feline-data.csv 파일을 생성하는데 나노 편집기(Nano)를 사용하거나, RStudio File -> New File -> Text File 메뉴를 사용할 수 있다.

다음 명령어를 통해서 R로 데이터를 불러 가져온다:

cats <- read.csv(file = "data/feline-data.csv")
cats
##     coat weight likes_string
## 1 calico    2.1            1
## 2  black    5.0            0
## 3  tabby    3.2            1

read.table 함수를 사용해서 텍스트 파일에 저장된 표형식 데이터를 불러오는데 사용한다. 표형식 데이터는 CSV (csv = 콤마구분 값) 같은 구분 문자(punctuation characters)로 칼럼이 구분된다. csv 파일에 데이터를 구분하는데 가장 일반적으로 사용되는 구분 문자가 탭과 콤마다. R에서 사용의 편리성을 위해서 read.table 함수에 두가지 다른 버전 함수를 제공한다. read.csv가 콤마로 구분되는 데이터를 읽어들이는데 사용하고, read.delim 함수가 탭으로 구분되는 데이터를 읽어오는데 사용된다. read.csv 함수가 둘중에 더 많이 사용된다. 필요한 경우 read.csv, read.delim 함수 모두 구분문자를 오버라이드해서 사용하는 것도 가능하다.

데이터프레임에 $ 연산자를 사용해서 칼럼을 뽑아내면서 데이터셋에서 바로 탐색을 시작하는 것도 가능하다.

cats$weight
## [1] 2.1 5.0 3.2
cats$coat
## [1] "calico" "black"  "tabby"

칼럼에 다른 연산자 적용도 할 수 있다:

## 내 고양이 몸무게가 2 kg 불었다고 다음과 같이 표현할 수 있다:
cats$weight + 2
## [1] 4.1 7.0 5.2
paste("My cat is", cats$coat)
## [1] "My cat is calico" "My cat is black"  "My cat is tabby"

이번에 다음은 어떤가?

cats$weight + cats$coat
## Error in cats$weight + cats$coat: non-numeric argument to binary operator

상기 문장에서 발생된 것을 이해하는 것이 R로 데이터 분석을 성공적으로 수행하는데 중요하다.

24.1 자료형

2.1 더하기 "black"이 말이 되지 않기 때문에 마지막 문장이 오류를 뱉어낼 것이라고 추측한다면, 제대로 이해하고 있는 것이다. 이미 자료형(data type)으로 불리는 프로그래밍의 중요한 개념에 대한 직관을 갖추고 있는 것이다. 데이터 자료형이 무엇인지 다음을 통해 물어보게 된다:

typeof(cats$weight)
## [1] "double"

다섯가지 주요 자료형이 있다: 실수형(double), 정수형(integer), 복소수형(complex), 논리형(logical), 문자형(character).

typeof(3.14)
## [1] "double"
typeof(1L) # The L suffix forces the number to be an integer, since by default R uses float numbers
## [1] "integer"
typeof(1+1i)
## [1] "complex"
typeof(TRUE)
## [1] "logical"
typeof('banana')
## [1] "character"

분석이 얼마나 복잡해지냐에 관계없이, R에서 모든 데이터는 이러한 기본 자료형 중 하나로 해석된다. 이러한 엄격함이 정말로 중요한 결과를 잉태하게 된다.

사용자가 또다른 고양이에 대한 상세내용을 추가했고, 추가 정보는 data/feline-data_v2.csv 파일에 저장되어 있다.

file.show("data/feline-data_v2.csv")
coat,weight,likes_string
calico,2.1,1
black,5.0,0
tabby,3.2,1
tabby,2.3 or 2.4,1

앞서와 마찬가지로 새로운 고양이 데이터를 불러와서 weight 칼럼에 데이터 자료형이 무엇인지 확인한다:

cats <- read.csv(file="data/feline-data_v2.csv")
typeof(cats$weight)
## [1] "character"

이러면 안되는데, 고양이 몸무게가 더이상 실수형 자료형이 아니다! 앞서 수행했던 동일한 수학연산을 취하게 되면 문제에 봉착한다:

cats$weight + 2
## Error in cats$weight + 2: non-numeric argument to binary operator

무슨 일이 일어난 걸까? R이 csv 파일을 불러올 때, 칼럼에 모든 것이 동일한 자료형이 되는 것을 요구한다; 칼럼에 모든 원소가 실수형으로 인식되지 않으면, 칼럼에 어떤 원소도 실수형이 될 수 없다. 고양이 데이터를 불러온 테이블을 데이터프레임(data.frame)이라고 부르고, 자료구조(data structure)로 불리는 첫번째 사례가 된다. 즉, 자료구조는 기본 자료형에서 R이 생성할 줄 아는 구조가 된다.

class 함수를 호출해서 데이터프레임인지를 알 수 있다:

class(cats)
## [1] "data.frame"

R에서 데이터를 성공적으로 사용하려면, 기본 자료구조가 무엇인지, 어떻게 동작하는지 이해할 필요가 있다. 지금으로서는 추가된 마지막 줄을 제거하고 좀더 살펴보도록 하자:

feline-data.csv:

coat,weight,likes_string
calico,2.1,1
black,5.0,0
tabby,3.2,1

RStudio로 다시 돌아와서:

cats <- read.csv(file="data/feline-data.csv")

24.2 벡터와 자료형 강제변환

강제변환(Type Coercion)을 보다 잘 이해하기 위해서, 또 다른 자료구조를 만나보자: 벡터(vector).

my_vector <- vector(length = 3)
my_vector
## [1] FALSE FALSE FALSE

R에서 벡터는 본질적으로 무언가 순서를 갖는 리스트로, 특별한 성질을 갖는데 벡터에 모든 것은 동일한 자료형을 갖는다는 점이다. 자료형을 지정하지 않게 되면, 기본디폴트 설정은 논리형(logical)이 되거나; 자료형에 관계없이 공벡터를 선언할 수 있다.

another_vector <- vector(mode='character', length=3)
another_vector
## [1] "" "" ""

자료가 벡터인지 다음과 같이 확인한다:

str(another_vector)
##  chr [1:3] "" "" ""

상기 명령어로부터 다소 암호스러운 출력결과가 나오는데 해당 벡터에서 발견된 기본 자료형은 이 경우 chr 문자; 벡터에 나와있는 숫자는 벡터의 인덱스로 이 경우 [1:3]; 그리고 벡터에 실제로 들어있는 몇가지 예로, 이 경우 빈 문자열이 된다. 유사하게 다음을 실행하게 되면;

str(cats$weight)
##  num [1:3] 2.1 5 3.2

cats$weight도 벡터임을 알 수 있다 - R 데이터프레임으로 불러온 데이터 칼럼은 모두 벡터다, 그리고 이러한 연유로 칼럼에 있는 모든 원소는 동일한 자료형을 갖게 강제하는 이유가 된다.

토론 1

왜 R에서는 데이터 칼럼에 무엇을 넣는지에 대해서 고집스럽게 주장을 할까? 이러한 점은 어떻게 우리에게 도움이 될까?

토론 1

칼럼에 모든 것을 동일하게 둠으로써, 데이터에 관해서 단순한 가정을 할 수 있게 한다; 만약 칼럼의 첫번째 입력값이 숫자라면, 모든 입력값을 숫자로 해석할 수 있게 되고, 그렇게 함으로써 모든 것을 확인할 필요가 없게 된다. 깨끗한 데이터(clean data)라고 사람들이 회자할 때, 사람들이 의미하는 것이 이러한 일관성이다. 장기적으로 엄격한 일관성이 R에서 우리 삶을 풍요롭고 수월하게 만들 것이다.

결합 함수(c())를 사용해서 벡터를 생성할 수 있다:

combine_vector <- c(2,6,3)
combine_vector
## [1] 2 6 3

지금까지 학습한 것을 바탕으로, 다음 문장은 어떤 결과를 출력하게 될까?

quiz_vector <- c(2,6,'3')

이것을 자료형 강제변환(type coercion)라고 부른다. 이것이 많은 놀라움의 원천이고, 왜 기본 자료형에 대해서 인지하고 있어야 되는 이유가 되고, R이 해석하는 방식도 알아야 된다. R에서 혼합된 자료형(상기 예제는 숫자와 문자)의 경우 단하나의 벡터로 변환시킬 때, 모든 자료를 동일한 자료형으로 강제 변환시킨다. 다음을 생각해 보자.

coercion_vector <- c('a', TRUE)
coercion_vector
## [1] "a"    "TRUE"
another_coercion_vector <- c(0, TRUE)
another_coercion_vector
## [1] 0 1

강제 변환규칙은 다음과 같이 적용된다: 논리형 -> 정수형 -> 숫자형 -> 복소수형 -> 문자형. 여기서 -> 표현은 다음으로 변환된다로 읽힌다. 이런 자동 변환규칙에 거슬러 자료형을 강제로 변환시키려면 as. 함수를 사용한다:

character_vector_example <- c('0','2','4')
character_vector_example
## [1] "0" "2" "4"
character_coerced_to_numeric <- as.numeric(character_vector_example)
character_coerced_to_numeric
## [1] 0 2 4
numeric_coerced_to_logical <- as.logical(character_coerced_to_numeric)
numeric_coerced_to_logical
## [1] FALSE  TRUE  TRUE

R이 기본 자료형을 다른 자료형으로 강제 변환할 때, 놀라운 일이 생겨난다! 자료형 강제변환에 대한 핵심사항은 차치하고 중요한 점은 다음과 같다: 본인 데이터가 생각한 바와 다르게 보인다면, 자료형 강제변환이 원인으로 지목되는 것이 당연하다; 벡터와 데이터프레임의 칼럼 자료형이 동일하도록 확실히 하라. 그렇지 않으면 끔찍한 놀라운 경험을 하게 될 것이다!

하지만, 경우에 따라서는 자료형 강제변환이 매우 유용할 수도 있다! 예를 들어, cats 데이터프레임 likes_string 칼럼은 숫자형이지만, 1과, 0이 실제로 TRUEFALSE를 표현한다는 것을 알고 있다. 이 경우 두 상태(TRUE 혹은 FALSE)를 갖는 논리형 자료형을 사용해야 한다. as.logical 함수를 사용해서 칼럼을 논리형(logical)으로 ‘강제변환(coerce)’ 시킨다:

cats$likes_string
## [1] 1 0 1
cats$likes_string <- as.logical(cats$likes_string)
cats$likes_string
## [1]  TRUE FALSE  TRUE

결합 함수(c())는 기존 벡터에 무언가 추가하는 역할을 수행한다:

ab_vector <- c('a', 'b')
ab_vector
## [1] "a" "b"
combine_example <- c(ab_vector, 'SWC')
combine_example
## [1] "a"   "b"   "SWC"

숫자 순열도 생성할 수 있다:

mySeries <- 1:10
mySeries
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(10)
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(1,10, by=0.1)
##  [1]  1.0  1.1  1.2  1.3  1.4  1.5  1.6  1.7  1.8  1.9  2.0  2.1  2.2  2.3  2.4
## [16]  2.5  2.6  2.7  2.8  2.9  3.0  3.1  3.2  3.3  3.4  3.5  3.6  3.7  3.8  3.9
## [31]  4.0  4.1  4.2  4.3  4.4  4.5  4.6  4.7  4.8  4.9  5.0  5.1  5.2  5.3  5.4
## [46]  5.5  5.6  5.7  5.8  5.9  6.0  6.1  6.2  6.3  6.4  6.5  6.6  6.7  6.8  6.9
## [61]  7.0  7.1  7.2  7.3  7.4  7.5  7.6  7.7  7.8  7.9  8.0  8.1  8.2  8.3  8.4
## [76]  8.5  8.6  8.7  8.8  8.9  9.0  9.1  9.2  9.3  9.4  9.5  9.6  9.7  9.8  9.9
## [91] 10.0

벡터에 관해 궁금한 점도 물어볼 수 있다:

sequence_example <- seq(10)
head(sequence_example, n=2)
## [1] 1 2
tail(sequence_example, n=4)
## [1]  7  8  9 10
length(sequence_example)
## [1] 10
class(sequence_example)
## [1] "integer"
typeof(sequence_example)
## [1] "integer"

마지막으로, 벡터의 각 원소에 명칭을 부여하는 것도 가능하다:

my_example <- 5:8
names(my_example) <- c("a", "b", "c", "d")
my_example
## a b c d 
## 5 6 7 8
names(my_example)
## [1] "a" "b" "c" "d"

24.3 도전과제 1

1 부터 26까지 숫자를 갖는 벡터를 생성하면서 시작해 보자. 생성한 벡터에 2를 곱해서 다시 자신에게 할당한다. 벡터에 A 부터 Z까지 이름을 부여한다. (힌트: LETTERS라는 내장벡터가 있다.)

도전과제 1에 대한 해답

x <- 1:26
x <- x * 2
names(x) <- LETTERS

24.4 데이터프레임

데이터프레임(Data Frames)의 칼럼이 벡터라고 앞에서 언급했다:

str(cats$weight)
##  num [1:3] 2.1 5 3.2
str(cats$likes_string)
##  logi [1:3] TRUE FALSE TRUE

말이 된다. 다음은 어떤가?

str(cats$coat)
##  Factor w/ 3 levels "black","calico",..: 2 1 3

24.5 범주형

또다른 중요한 자료구조가 범주형(factor)이다. 범주형은 보통 문자 데이터처럼 생겼다. 하지만, 일반적으로 범주형 정보를 나타내는데 사용된다. 예를 들어, 연구중인 모든 고양이에 대한 색상을 문자열 벡터로 만들어보자:

coats <- c('tabby', 'tortoiseshell', 'tortoiseshell', 'black', 'tabby')
coats
## [1] "tabby"         "tortoiseshell" "tortoiseshell" "black"        
## [5] "tabby"
str(coats)
##  chr [1:5] "tabby" "tortoiseshell" "tortoiseshell" "black" "tabby"

문자열 벡터를 요인형으로 바꾸면 다음과 같다:

CATegories <- factor(coats)
class(CATegories)
## [1] "factor"
str(CATegories)
##  Factor w/ 3 levels "black","tabby",..: 2 3 3 1 2

이제 R은 데이터에 3가지 가능한 범주가 있음을 파악하게 되었다 - 하지만, 놀라운 것도 함께 수행했다; 문자열을 출력하는 대신에, 숫자가 대량으로 출도되었다. R은 내부적으로 사람이 읽을 수 있는 범주를 숫자 인덱스로 치환시킨다. 이런 기능은 대다수 통계 계산에서 범주형 데이터를 숫자형으로 표현되는 기능을 활용하기 때문에 꼭 필요하다.

typeof(coats)
## [1] "character"
typeof(CATegories)
## [1] "integer"

24.6 도전과제 2

cats 데이터프레임에 요인형 칼럼이 있나요? 요인형 칼럼의 이름은 무엇인가요? ?read.csv 명령어를 사용해서 텍스트 칼럼을 요인형 대신에 문자형으로 그대로 유지시키는 방법을 찾아내세요; 그리고 나서 cat 데이터프레임의 요인이 실제로 문자벡터임을 확인하는 명령문을 작성하시오.

도전과제 2에 대한 해답

해법으로 stringAsFactors 인자를 사용하면 된다.:

cats <- read.csv(file="data/feline-data.csv", stringsAsFactors=FALSE)
str(cats$coat)

또다른 해법은 colClasses 인자를 사용해서 칼럼을 좀더 면밀히 제어하는 것이다.

cats <- read.csv(file="data/feline-data.csv", colClasses=c(NA, NA, "character"))
str(cats$coat)

주의: 도움말 파일이 이해하기 어렵다는 학생이 다수 있다; 도움말 파일을 이해하기 어렵다는 것이 일반적이라서, 확신하지는 못하더라도, 문맥에 기초하여 최대한 추측하도록 용기를 주도록 한다.

모형 함수에서 기준 수준(baseline level)이 무엇인지 파악하는 것이 중요하다. 요인의 첫번째 범주로 가정하지만, 기본디폴트는 알파벳순으로 정해지게 되어 있다. 수준을 다음과 같이 지정해서 변경할 수 있다:

mydata <- c("case", "control", "control", "case")
factor_ordering_example <- factor(mydata, levels = c("control", "case"))
str(factor_ordering_example)
##  Factor w/ 2 levels "control","case": 2 1 1 2

상기 경우 “control”를 1로, “case”를 2로 명시적으로 지정하도록 했다. 이러한 지정이 통계 모형 결과를 해석하는데 있어 매우 중요하다.

24.7 리스트

데이터 과학자로서 알고 있어야 되는 또다른 자료구조가 리스트(list)다. 리스트는 다른 자료형과 비교하여 몇가지 점에서 더 단순하다. 왜냐하면 원하는 무엇이든 넣을 수 있기 때문이다:

list_example <- list(1, "a", TRUE, 1+4i)
list_example
## [[1]]
## [1] 1
## 
## [[2]]
## [1] "a"
## 
## [[3]]
## [1] TRUE
## 
## [[4]]
## [1] 1+4i
another_list <- list(title = "Numbers", numbers = 1:10, data = TRUE )
another_list
## $title
## [1] "Numbers"
## 
## $numbers
##  [1]  1  2  3  4  5  6  7  8  9 10
## 
## $data
## [1] TRUE

데이터프레임에서 다소 놀라운 것을 이제 이해할 수 있다; 다음을 실행하게 되면 무슨 일이 발생될가:

typeof(cats)
## [1] "list"

데이터프레임은 ‘내부적으로(under the hood)’ 리스트라는 것을 알 수 있다 - 이유는 데이터프레임이 실제로 벡터와 요인으로 구성된 리스트이기 때문이다. 벡터와 요인으로 뒤섞인 칼럼을 붙잡아 두려면, 데이터프레임은 모든 칼럼을 유사한 표에 담을 수 있는 벡터보다 더 유연할 필요가 있다. 다른 말로, data.frame은 모든 벡터가 동일한 길이를 갖는 특별한 리스트로 정의할 수 있다.

cats 사례에서는 정수형, 숫자형, 논리형 변수로 구성된다. 이미 살펴봤듯이, 데이터프레임 각 칼럼은 벡터다.

cats$coat
## [1] calico black  tabby 
## Levels: black calico tabby
cats[,1]
## [1] calico black  tabby 
## Levels: black calico tabby
typeof(cats[,1])
## [1] "integer"
str(cats[,1])
##  Factor w/ 3 levels "black","calico",..: 2 1 3

각 행은 다른 변수의 관측점(observation)으로 그 자체로 데이터프레임이다. 따라서, 서로 다른 자료형을 갖는 원소로 구성되어진다.

cats[1,]
##     coat weight likes_string
## 1 calico    2.1         TRUE
typeof(cats[1,])
## [1] "list"
str(cats[1,])
## 'data.frame':    1 obs. of  3 variables:
##  $ coat        : Factor w/ 3 levels "black","calico",..: 2
##  $ weight      : num 2.1
##  $ likes_string: logi TRUE

24.8 도전과제 3

데이터프레임에서 변수와 관측점과 원소를 호출하는 미모하지만 다른 방식이 존재한다:

  • cats[1]
  • cats[[1]]
  • cats$coat
  • cats["coat"]
  • cats[1, 1]
  • cats[, 1]
  • cats[1, ]

상기 예제를 시도해보고, 각각이 반환하는 것을 설명해 본다. 힌트: typeof() 함수를 사용해서 각각의 경우에 반환되는 것을 꼼꼼히 살펴본다.

도전과제 3에 대한 해답

cats[1]
##     coat
## 1 calico
## 2  black
## 3  tabby

데이터프레임을 벡터로 구성된 리스트로 간주할 수 있다. 단일 꺾쇠 [1]은 리스트의 첫번째 원소를 리스트로 반환한다. 이번 경우, 데이터프레임의 첫번째 칼럼이 된다.

cats[[1]]
## [1] calico black  tabby 
## Levels: black calico tabby

이중 꺾쇠 [[1]]은 리스트의 원소 내용물을 반환한다. 이번 경우, 리스트가 아닌 요인형 벡터로 첫번째 칼럼 내용물을 반환한다.

cats$coat
## [1] calico black  tabby 
## Levels: black calico tabby

명칭으로 항목을 끄집어내는데 $ 기호를 사용한다. _coat_가 데이터프레임의 첫번째 칼럼으로 요인형 벡터가 반환된다.

cats["coat"]
##     coat
## 1 calico
## 2  black
## 3  tabby

["coat"] 방식은 칼럼 인덱스를 명칭으로 바꾸고 동시에 꺾쇠를 사용한 경우다. 예제 1과 마찬가지로 반환되는 객체는 리스트가 된다.

cats[1, 1]
## [1] calico
## Levels: black calico tabby

단일 꺾쇠를 사용했는데 이번에는 행과 열의 좌표도 넣어 전달했다. 반환되는 객체는 첫번째 행, 첫번째 열에 교차하는 값이 된다. 반환되는 객체는 정수형이지만, 요인형 벡터의 일부분이라 정수값과 연관된 라벨 “calico”도 함께 출력한다.

cats[, 1]
## [1] calico black  tabby 
## Levels: black calico tabby

앞선 예제와 마찬가지로 꺾쇠를 하나만 사용했고, 행과 열 좌표도 전달했다. 행좌표를 지정하지 않은 경우, R에서 결측값은 해당 칼럼 벡터의 모든 원소로 해석된다.

cats[1, ]
##     coat weight likes_string
## 1 calico    2.1         TRUE

다시 한번, 꺽쇠를 하나만 사용했고, 행과 열 좌표도 전달했다. 칼럼 좌표가 지정되어 있지 않기 때문에, 첫번째 행의 모든 값을 포함하는 리스트가 반환된다.

24.9 행렬

마지막으로 중요한 자료형이 행렬(Matrices)이다. 0으로 가득찬 행렬을 다음과 같이 선언한다:

matrix_example <- matrix(0, ncol=6, nrow=3)
matrix_example
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    0    0    0    0    0    0
## [2,]    0    0    0    0    0    0
## [3,]    0    0    0    0    0    0

다른 자료구조와 마찬가지로, 행렬에 질문을 다음과 같이 던질 수 있다:

class(matrix_example)
## [1] "matrix" "array"
typeof(matrix_example)
## [1] "double"
str(matrix_example)
##  num [1:3, 1:6] 0 0 0 0 0 0 0 0 0 0 ...
dim(matrix_example)
## [1] 3 6
nrow(matrix_example)
## [1] 3
ncol(matrix_example)
## [1] 6

24.10 도전과제 4

length(matrix_example) 실행결과는 어떻게 나올까? 시도해보자. 생각한 것과 일치하는가? 왜 그런가/ 왜 그렇지 않는가?

도전과제 4에 대한 해답

length(matrix_example) 실행결과는 어떻게 나올까?

matrix_example <- matrix(0, ncol=6, nrow=3)
length(matrix_example)
## [1] 18

행렬은 차원 속성이 추가된 벡터라서, length() 함수는 행렬의 전체 원소 갯수를 반환시킨다.

24.11 도전과제 5

또다른 행렬을 만들어 보자. 이번에는 1:50 숫자를 담고 있는 칼럼이 5, 행이 10일 행렬이다. matrix() 함수로 칼럼기준으로 혹은 행기준으로 채울 수 있나요? 행과 열을 바꿔 변경할 수 있는 방법을 찾아보자. (힌트: matrix 도움말 문서를 참조한다!)

도전과제 5에 대한 해답

또다른 행렬을 만들어 보자. 이번에는 1:50 숫자를 담고 있는 칼럼이 5, 행이 10일 행렬이다. matrix() 함수로 칼럼기준으로 혹은 행기준으로 채울 수 있나요? 행과 열을 바꿔 변경할 수 있는 방법을 찾아보자. (힌트: matrix 도움말 문서를 참조한다!)

x <- matrix(1:50, ncol=5, nrow=10)
x <- matrix(1:50, ncol=5, nrow=10, byrow = TRUE) # to fill by row

24.12 도전과제 6

이번 워크샵에서 다룬 각 섹션별 문자벡터를 포함하는 길이 2을 갖는 리스트를 생성하시오.

  • 자료형(Data types)
  • 자료구조(Data structures)

지금까지 살펴본 자료형(data type)과 자료구조(data structure)를 명칭으로 갖는 문자 벡터를 채워넣는다.

도전과제 6에 대한 해답

dataTypes <- c('double', 'complex', 'integer', 'character', 'logical')
dataStructures <- c('data.frame', 'vector', 'factor', 'list', 'matrix')
answer <- list(dataTypes, dataStructures)

주목: 칠판이나 벽에 자료형과 자료구조를 모두 적어두는 것이 도움이 될 수 있다 - 워크샵 동안 참여자들에게 기본 자료형과 구조의 중요성을 상기할 수 있기 때문이다.

24.13 도전과제 7

아래 행렬의 출력 결과를 생각해보자:

##      [,1] [,2]
## [1,]    4    1
## [2,]    9    5
## [3,]   10    7

이 행렬을 작성하는 올바른 명령어는 다음 중 무엇일까? 직접 타이핑하기 전에 각 명령어를 살펴보고, 정답을 생각해보자. 다른 명령어는 어던 행렬을 만들어낼지도 생각해본다.

  1. matrix(c(4, 1, 9, 5, 10, 7), nrow = 3)
  2. matrix(c(4, 9, 10, 1, 5, 7), ncol = 2, byrow = TRUE)
  3. matrix(c(4, 9, 10, 1, 5, 7), nrow = 2)
  4. matrix(c(4, 1, 9, 5, 10, 7), ncol = 2, byrow = TRUE)

도전과제 7에 대한 해답

아래 행렬의 출력 결과를 생각해보자:

##      [,1] [,2]
## [1,]    4    1
## [2,]    9    5
## [3,]   10    7

이 행렬을 작성하는 올바른 명령어는 다음 중 무엇일까? 직접 타이핑하기 전에 각 명령어를 살펴보고, 정답을 생각해보자. 다른 명령어는 어던 행렬을 만들어낼지도 생각해본다.

matrix(c(4, 1, 9, 5, 10, 7), ncol = 2, byrow = TRUE)