identical, all equal 함수의 차이

identical(), all.equal() 함수의 차이

  • R은 두 객체가 같은지를 비교하는 함수로 identical()과 all.equal()을 지원한다.
  • 한데, 두 함수에는 차이가 있다. identical 함수는 두 개의 객체가 “정확히(exactly)” 같은지를 비교한다: 같다면 TRUE, 다르다면 FALSE를 반환한다. 반면, all.equal 함수는 미미한 오차를 무시하고, 두 변수가 다른 경우 그 차이의 값을 반환한다(R Documentation, all.equal 함수 설명).


  • 이를테면 다음의 예시를 보자. 여기서 변수 x는 numeric이며 y는 integer이다. identical 함수는 이 둘이 다르다고 엄격히 판단해 FALSE를 반환하며, all.equal 함수는 변수 유형은 다르나 값이 같기 때문에 TRUE를 반환하는 것을 볼 수 있다.
x <- 1; y <- 1L
identical(x, y)
## [1] FALSE
all.equal(x, y)
## [1] TRUE


그렇다면 값이 아주 약간 다른 두 변수에 대해 all.equal 함수는 어떻게 판단할까? 아래의 코드에서 변수 approxe는 매클로린 급수를 사용해 10차 항까지 오일러 수 e를 근사한 것이고, 변수 e는 R의 기본 지수함수를 사용해 만들어진 오일러 수 e이다. 이 둘을 all.equal 함수는 같다고 판단함을 아래에서 볼 수 있다. (어느 오차까지를 눈 감아 줄 것이냐를 tolerance argument를 사용해 설정할 수 있는데, 기본값은 약 1.5e-8이다.)

\[ \text{approxe} = \sum_{n=0}^{10}\frac{1}{n!} \approx e \]

emake <- function(){
  e <- 0
  for (n in 0:10){
    e <- e + 1/(factorial(n))
  }
  return(e)
}
approxe <- emake(); e <- exp(1)
all.equal(e, approxe)
## [1] TRUE
identical(e, approxe)
## [1] FALSE
  • 한편 all.equal 함수에 tolerance argument를 추가해 어느 정도의 오차까지를 허용할지 결정할 수 있다.
all.equal(e, approxe, tolerance = 0)
## [1] "Mean relative difference: 1.004777e-08"

'기타 공부' 카테고리의 다른 글

[R] 함수 만들기 기초  (0) 2018.06.03
[R] 자료 객체 (3): 배열 (array)  (0) 2018.06.03
[R] 자료 객체 (2): 행렬 matrix  (0) 2018.05.27
[R] 자료 객체 (1): 벡터 vector  (0) 2018.05.27
[R] 변수 할당 및 데이터 유형  (0) 2018.05.27
R 행렬과 배열

이 글에서는 R의 자료 객체(data objects) 중 행렬에 대해 다뤄보고자 한다.

행렬

  • 행렬은 동일한 유형의 데이터로 구성된, 2차원 이상의 자료 구조를 갖는 객체이다.
  • 행렬은 다음과 같이 만들 수 있다.
    • matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
  • data에는 벡터가 들어간다. nrow, ncol은 행, 열의 수를 지정하는 것.
  • byrow: 기본값은 FALSE이며, TRUE일 경우 ‘열벡터’ 순서로 채운다. 예시를 참고.
  • dimnames: 각 행과 열의 이름 정의

  • 중요한 함수들
    • nrow(): 행의 개수
    • ncol(): 열의 개수
    • dim(): 행렬의 크기
    • length(): 전체 원소 개수
A <- matrix(c(1:9), nrow = 3, ncol = 3)
At <- matrix(c(1:9), nrow = 3, ncol = 3, byrow = TRUE)
A; At
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9
B = matrix(1:6, nrow = 2, ncol = 3, byrow = TRUE,
              dimnames = list(c("row1", "row2"), c("col1", "col2", "col3")))
B
##      col1 col2 col3
## row1    1    2    3
## row2    4    5    6


행렬의 연산

  • 원소 대 원소로 계산되는 연산은 다음과 같은 것들이 있다.
    • +, -, *, ==, !=, <, >, <=, >= 등은 원소 대 원소로 계산된다.
    • 특히 R에서 *는 일반적으로 정의되는 행렬곱과는 다르기 때문에 주의 요망.
  • (고등학교에서 배우는) 행렬곱은?
    • %*%로 정의
  • 기타 행렬 연산
    • 전치 행렬(transpose): t()
    • 역행렬: solve()
    • Cross product: crossprod(X, Y) = t(X) %*% Y
    • 대각행렬: diag()


  • 행렬 연산자를 배웠다면, 간단한 선형대수 지식으로 다음 Overdetermined linear system의 least squares solution을 구해볼 수 있다.

\[ \begin{cases} 3x_1+x_2-x_3=-3 \\ x_1+2x_2=-3 \\ x_2+2x_3=8 \\ x_1+x_2-x_3=9 \end{cases} \]

A <- matrix(c(3, 1, 0, 1, 1, 2, 1, 1, -1, 0, 2, -1), nrow = 4, ncol = 3)
b <- c(-3, -3, 8, 9)
lss <- solve((t(A)%*%A)) %*% t(A) %*% b
lss
##      [,1]
## [1,]   -1
## [2,]    2
## [3,]    1


행렬의 인덱싱

  • 부분벡터(subvector)에서 했던 것과 비슷한 것을 행렬에 대해서도 할 수 있다.
A[3,] # 세 번째 행 추출 
## [1] 0 1 2
A[, 2] # 두 번째 열 추출 
## [1] 1 2 1 1
A[1, 1] # (1, 1) 원소 추출 
## [1] 3
A[, 1:3] # 1에서 3번째 열 추출 
##      [,1] [,2] [,3]
## [1,]    3    1   -1
## [2,]    1    2    0
## [3,]    0    1    2
## [4,]    1    1   -1
A[-1, ] # 1번째 행을 제외한 것 모두 추출 
##      [,1] [,2] [,3]
## [1,]    1    2    0
## [2,]    0    1    2
## [3,]    1    1   -1
A[c(TRUE, FALSE, FALSE, TRUE), ]
##      [,1] [,2] [,3]
## [1,]    3    1   -1
## [2,]    1    1   -1

행렬, 벡터의 결합

  • 열 간의 결합: rbind()
  • 행 간의 결합: cbind()
  • 기본적 사용은 직관적이지만 앞에서 배운 인덱싱을 활용해 볼 수 있다.
X <- matrix(1:9, nrow = 3, ncol = 3, byrow = TRUE)
Y <- matrix(11:19, nrow = 3, ncol = 3, byrow = TRUE)
XY1 <- cbind(X[, 1], Y[, 2])
cbind(X, Y) # 행렬 간의 결합도 가능. 
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    1    2    3   11   12   13
## [2,]    4    5    6   14   15   16
## [3,]    7    8    9   17   18   19
Z <- matrix(1:6, nrow = 2, ncol = 3)
XZ <- cbind(X[, 1], Z); XZ # 경고 메시지 출력 
## Warning in cbind(X[, 1], Z): number of rows of result is not a multiple of
## vector length (arg 1)
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    3    5
## [2,]    4    2    4    6
x = 1:10
is.matrix(cbind(x)) # cbind 함수의 결과는 벡터가 아닌 행렬로 간주
## [1] TRUE
R 벡터

이 글에서는 R의 자료 객체(data objects) 중 벡터에 대해 다뤄보고자 한다.

벡터

  • 벡터는 데이터들의 묶음인데, 벡터 안의 데이터들은 한 가지 유형으로만 구성된다. 아래는 예시이다.
char <- c(1.5, 3L, "r", "markdown")
class(char)
## [1] "character"
  • 벡터 데이터들의 나열 원소는 의미를 가진다.

벡터 생성하기

c() 함수, 연산자 “:”

  • 앞서 본 것처럼 c() 함수를 이용한다.
    • 여기서 흥미로운 것(?)은 벡터끼리의 결합이 가능하다는 것이다.
  • is.vector()를 사용해 주어진 객체가 벡터인지 확인할 수 있다.
  • 연산자 “:”을 사용하면 노가다를 하지 않을 수 있다. “a:b”는 a가 초항이고 b가 끝 항인, 공차가 1인 등차수열을 의미한다. a, b는 음의 수여도 상관 없다.
    • 연산자 “:”는 우선순위를 가진다. 아래의 식을 보면, R은 1:10의 연산을 먼저 처리해 1부터 10까지의 길이가 10인 벡터를 생성하고, 그 벡터 각각의 원소에 대해 1을 더하는 연산을 마지막으로 수행했음을 알 수 있다.
vec1 <- c(1, 2, 3)
vec2 <- c(vec1, 4, 5, 6); vec2
## [1] 1 2 3 4 5 6
vec3 <- c(6:-3)
1 : 10 + 1 # 연산자 :의 우선순위
##  [1]  2  3  4  5  6  7  8  9 10 11
  • 한편, 벡터 각 성분의 이름을 부여하는 것 역시 가능하다. names() 함수는 벡터의 이름을 불러온다. 방법은 다음과 같다.
vec_name <- c(one=1, two=2)
names(vec_name)
## [1] "one" "two"


rep() 함수

  • rep 함수는 한 대상을 반복해 주는 함수이다. 함수는 다음과 같은 구문으로 구성된다.
  • rep(x, times = n, length.out = NA, each = m)
    • 여기서 x는 반복대상으로, 벡터나 팩터 모두 될 수 있다.
    • times는 말 그대로 반복횟수이다.
    • length.out은 출력자료의 객체 길이를 제한하는 데에 쓰인다.
    • each는 벡터 내 데이터 원소 각각의 반복 횟수이다.
rep(c(0, 1), times = 3, each = 2)
##  [1] 0 0 1 1 0 0 1 1 0 0 1 1
rep(c(0, 1), 5, length.out = 5)
## [1] 0 1 0 1 0
rep(0, 10)
##  [1] 0 0 0 0 0 0 0 0 0 0


seq() 함수

  • seq(from = n, to = m, by = x, length.out = NULL, along.with = NULL)
  • seq는 말 그대로 수열을 생성해주는 함수이다. by는 증분(incremental)을 의미하고, length.out은 앞의 rep 함수에서 살펴본 것처럼 출력자료(수열)의 길이를 지정해 준다.
    • from과 to에는 숫자만이 올 수 있다.
    • by를 생략하는 대신 length.out을 지정하면, 증분이 수열 길이에 맞춰 적절히 설정되는 것을 볼 수 있다.
  • along.with는 지정한 객체와 같은 길이의 수열을 생성해 준다.
seq(from = 1, to = 10) # 1:10과 동일한 기능
##  [1]  1  2  3  4  5  6  7  8  9 10
seq(from = 0.5, to = 10.9, by = 3)
## [1] 0.5 3.5 6.5 9.5
seq(from = 1, to = 5, length.out = 10)
##  [1] 1.000000 1.444444 1.888889 2.333333 2.777778 3.222222 3.666667
##  [8] 4.111111 4.555556 5.000000
x = 1:5
seq(3, 5, along.with = x)
## [1] 3.0 3.5 4.0 4.5 5.0


vector() 함수

  • vector(mode = “”, length = n)
  • mode에는 logical, integer, list, double, character 등이 올 수 있다.

부분벡터 (subvector)

  • 벡터 이름 뒤에 대괄호[]를 붙여 부분벡터를 활용할 수 있다.
abc <- vector(mode = "logical", length = 3)
abc[2] = TRUE
abc
## [1] FALSE  TRUE FALSE
x <- 1:10
x[3] # 3번째 성분 출력 
## [1] 3
x[-3] # 3번째를 제외한 성분 출력
## [1]  1  2  4  5  6  7  8  9 10
x[c(1, 3, 5)] <- 0; x
##  [1]  0  2  0  4  0  6  7  8  9 10
y <- 1:4
y[c(TRUE, FALSE, TRUE, FALSE)]
## [1] 1 3


벡터의 연산

  • 벡터 연산의 기본 원칙은 성분 대 성분이다.
    • 연산하는 두 벡터의 길이가 같은 경우 대응되는 각 성분끼리 연산을 한다.
    • 길이가 다른 경우 긴 벡터의 길이에 맞춰져 길이가 작은 벡터가 재활용된다. (warning 출력)
e <- c(exp(1), exp(2), exp(3))
log(e); sum(e); prod(e); max(e)
## [1] 1 2 3
## [1] 30.19287
## [1] 403.4288
## [1] 20.08554
m <- 1:5
n <- 1:3 
m + n
## Warning in m + n: longer object length is not a multiple of shorter object
## length
## [1] 2 4 6 5 7
  • R에서는 scalar와 vector의 addition을 어떻게 처리할까? 보통 이 둘은 더해지지 못하나 R에서는 그냥 더한다. (element by element.) scalar와 vector의 곱은 일반적으로 생각하는 것과 같다.
  • 벡터 간의 비교 연산
    • 모든 성분의 값이 TRUE 인지 확인하려면 all() 함수 사용
    • TRUE 성분이 적어도 하나 존재하는지 확인하려면 any() 함수 사용
add <- 1:3
add + 1
## [1] 2 3 4
add * 2
## [1] 2 4 6
# 벡터 간의 비교 연산
p <- 1:10; q <- -5:4; r <- 11:13
p <= 5
##  [1]  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
p > q
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
p < q
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
p > r # 벡터 길이가 다르기에 warning 출력
## Warning in p > r: longer object length is not a multiple of shorter object
## length
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
any (p > q)
## [1] TRUE
all (p < r)
## Warning in p < r: longer object length is not a multiple of shorter object
## length
## [1] TRUE


R 공부

변수

  • 변수명 부여 규칙은?
    • 문자, 숫자, ‘.’, ’_’ 사용
    • 대소문자 구분함
    • 한글 사용 불가
    • if, for 등 사용 불가
  • 할당하는 법: = 혹은 <- 사용함.

변수 확인 및 제거

  • 변수 혹은 객체 확인: objects(), ls()
  • 변수 제거: remove() 함수 혹은 rm() 함수 사용
    • 모든 변수 제거: rm(list = ls())

변수 데이터 유형

변수 유형에는 다음과 같은 것들이 있다.

  1. 숫자형 (numeric)
  2. 문자형 (character)
  3. 날짜형 (date)
  4. 논리형 (logical)
  5. 복소수형 (complex)
  • 변수에 저장된 값의 데이터 유형은 class() 또는 mode() 로 확인
num <- 3.14159265358979; class(num)
## [1] "numeric"
int <- 3L; mode(int)
## [1] "numeric"
text <- "abc"; class(text)
## [1] "character"
log <- TRUE; class(log)
## [1] "logical"
comp <- 1 + 2i; class(comp)
## [1] "complex"

숫자형 데이터

  • numeric: 정수, 소숫점 이하, 양수, 음수, 0 등.
  • integer: 변수 할당 시 숫자 끝에 ‘L’ 붙여 사용
  • is.numeric, as.numeric: 변수가 numeric인지 확인
is.numeric(int)
## [1] TRUE
is.numeric(num)
## [1] TRUE
int2 <- as.integer(num)
num2 <- as.numeric(int)
class(int2)
## [1] "integer"
class(num2)
## [1] "numeric"

문자형 데이터

  • character 형과 factor 형
    • factor 형: 범주형 자료에 사용됨
  • nchar() 함수: 문자열의 길이 계산. 공백 포함.
nchar(text)
## [1] 3
num_char <- as.character(num)

논리형 데이터

  • 참은 1, 거짓은 0이다.
  • isTRUE로 참인지 확인 (isFALSE 함수는 없음 )
  • 논리 연산자: & (and), | (or)
isTRUE(num)
## [1] FALSE
isTRUE(0)
## [1] FALSE
10 == 20
## [1] FALSE
"가나" > "가가"
## [1] TRUE
x = 1; y = 2
(x == 1) & (y == 2)
## [1] TRUE
(x == 0 | y ==2)
## [1] TRUE

맥북 포맷 후기

2018. 5. 26. 12:56
배경 
  • OSX 엘 캐피탄부터 하이 시에라까지 클린 설치 없이 업그레이드로 맥북을 써 왔음. 

문제들 
  1. 무선랜이 매우 굼뜨게 잡힘. 잡혔다가 끊기는 경우가 왕왕 있고, eduroam 등 학교 인터넷으로 접속할 때 특히 그러했음. 두세 번 반복하면 잘 연결되나 성가신 문제. 
  2. 아이폰/맥북 간 ‘연속성’ 기능이 안 됨. (e.g. 클립보드 연동, 문자/전화 연동.) 
  3. iCloud 음악 보관함 사용시, 맥북에서 업로드한 음악을 다른 기기에서 들을 때 중간에 끊기는 문제 발생. 예를 들자면, 4분 짜리 음악 A를 맥에서 업로드 해 아이폰에서 들을 때, 3분 50초 경에 음악 재생이 중단되고 다음 재생 목록으로 넘어가는 식. 
  4. iCloud 음악 보관함이 iTunes에서 작동되지 않는 문제 간혹 발생 (아이튠즈 계정을 로그아웃-로그인함으로써 일시적으로 해결 가능) 
  5. 상단 바에서 와이파이 아이콘을 클릭해 무선랜 접속하려고 할 때, 무선랜 목록이 매우 느리게 뜸. 

포맷 
  • USB 메모리에 부팅 디스크 설치 
  • OSX High Sierra 설치
  • 약 1시간 반 걸림 

문제 해결 현황 
  1. 해결됨. 무선랜이 깔끔하게 자동으로 잘 잡힘. 
  2. 해결됨.
  3. 해결됨. 
  4. (아직까지는) 해결된 것으로 보임.
  5. 해결됨. 






'생각들' 카테고리의 다른 글

the witness  (0) 2020.12.22
대학원 과목 이름에서 '연습'에 대한 고찰  (0) 2019.01.24
아이폰 이어폰 단자 수리 후기  (0) 2018.05.26
데이비드 포스터 월리스의 에세이  (0) 2018.05.08