R에서도 집합연산을 수행할 수 있는 여러 유용한 함수를 제공한다.
2005-06-22 네이버 블로그에 게시된 내용을 옮겨 온 글입니다. 지금의 R 환경과 다소 내용이 다를 수 있음을 밝여둡니다. R에서의 집합연산에 대해서 알아보자.
먼저 집합 x와 y를 만들어 보자. 두 개의 벡터는 이후에 집한 연산에서 계속 사용될 데이터다.
[1] 2 3 4 5 7
[1] 1 2 3 7 9
합집합은 union()
함수를 사용한다.
union(x, y)
[1] 2 3 4 5 7 1 9
그리고 unique()
함수를 응용해서 구할 수도 있다. unique()
함수는 벡터에 대해서 유일(unique)한 값을 구한다.
[1] 2 3 4 5 7 1 9
교집합은 intersect()
함수를 사용한다.
intersect(x, y)
[1] 2 3 7
그리고 unique()
함수와 sort()
함수를 응용해서 구할 수도 있다. sort()
함수는 정렬함수다.
[1] 2 3 7
또한 다음과 같이 구할 수도 있다.
[1] 2 3 7
사실 R에서 intersect()
함수가 이와 같이 정의되어 있다.
intersect
function (x, y)
{
y <- as.vector(y)
unique(y[match(as.vector(x), y, 0L)])
}
<bytecode: 0x7faa90cda870>
<environment: namespace:base>
차집합은 setdiff()
함수를 사용한다.
setdiff(x, y) # x-y
[1] 4 5
setdiff(y, x) # y-x
[1] 1 9
그리고 intersect() 함수를 응용해서 구할 수도 있다.
[1] 4 5
[1] 1 9
R의 setdiff()
함수는 다음과 같이 정의되어 있다.
setdiff
function (x, y)
{
x <- as.vector(x)
y <- as.vector(y)
unique(if (length(x) || length(y))
x[match(x, y, 0L) == 0L]
else x)
}
<bytecode: 0x7faa909ce240>
<environment: namespace:base>
is.element()
함수를 이용해서 특정 원소가 집합에 포함되는지를 검증할 수 있다. 단, 이 함수의 반환값은 논리 벡터인데 그 원소의 개수가 함수의 첫번째 인수의 개수와 동일하다.
a <- 9
is.element(a,x) # a ∈ x
[1] FALSE
is.element(a,y) # x ∈ y
[1] TRUE
그리고 as.logical()
함수와 sum()
함수를 응용해서 구할 수도 있다.
as.logical(sum(x == a)) # a ∈ x
[1] FALSE
as.logical(sum(y == a)) # a ∈ y
[1] TRUE
다음과 같은 방법을 사용할 수도 있다.
[1] FALSE
[1] TRUE
[1] FALSE
[1] TRUE
또한 다음처럼 구할 수도 있다.
match(a, x, 0) > 0
[1] FALSE
match(a, y, 0) > 0
[1] TRUE
R에서 is.element()
함수가 이와 같이 정의되어 있다.
is.element
function (el, set)
match(el, set, 0L) > 0L
<bytecode: 0x7faa90e0cc90>
<environment: namespace:base>
is.element()
함수를 이용해서 특정 집합이 집합에 포함되는지를 검증할 수 있다. 단, is.element()
함수의 반환값은 논리 벡터인데 그 원소의 개수가 함수의 첫번째 인수의 개수와 동일하기 때문에 prod()
함수를 이용하였다.
z <- c(2, 8)
as.logical(prod(is.element(z, x))) # z ⊂ x
[1] FALSE
as.logical(prod(is.element(z, y))) # z ⊂ y
[1] FALSE
as.logical(prod(is.element(x, z))) # x ⊂ z
[1] FALSE
그리고 as.logical()
함수와 prod()
함수, intersect()
함수를 응용해서 구할 수도 있다.
as.logical(prod(intersect(x, z)==z)) # z⊂x
[1] FALSE
as.logical(prod(intersect(y, z)==z)) # z⊂y
[1] FALSE
# 원소의 개수가 배수가 아니면 경고가 발생한다.
as.logical(prod(intersect(x, z)==x))
[1] FALSE
다음을 응용할 수도 있다.
match(z, x, 0) > 0
[1] TRUE FALSE
match(z, y, 0) > 0
[1] TRUE FALSE
match(x, z, 0) > 0
[1] TRUE FALSE FALSE FALSE FALSE
[1] FALSE
[1] FALSE
[1] FALSE
all(is.element(z, x)) # z ⊂ x
[1] FALSE
all(is.element(z, y)) # z ⊂ y
[1] FALSE
all(is.element(x, z)) # x ⊂ z
[1] FALSE
all()
함수는 인수의 값이 모두 TRUE일 경우에만 TRUE를 반환하고 아니면 FALSE를 반환한다.
is.element()
함수를 응용하면 sort(unique(c(x, y)))[table(c(x, y)) == 2]을 다음과 같이 간략화 시킬 수 있다.
x[is.element(x, y)] # x ∩ y
[1] 2 3 7
y[is.element(y, x)] # y ∩ x
[1] 2 3 7
is.element() 함수를 응용하면 intersect(sort(unique(c(x, y)))[table(c(x, y)) == 1], x)을 다음과 같이 간략화 시킬 수 있다.
x[!is.element(x, y)] # x - y
[1] 4 5
y[!is.element(y, x)] # y - x
[1] 1 9
setequal()
함수를 이용하여 집합의 상등을 알아볼 수 있다.
setequal(x, y)
[1] FALSE
setequal(x, x)
[1] TRUE
setequal()
함수는 다음과 같이 정의되어 있다.
setequal
function (x, y)
{
x <- as.vector(x)
y <- as.vector(y)
!(anyNA(match(x, y)) || anyNA(match(y, x)))
}
<bytecode: 0x7faa6632af98>
<environment: namespace:base>
이 함수를 수식으로 표현하자면 다음과 같다.
if x ⊂ y and y ⊂ x then x = y othwise x ≠ y
다음처럼 구할 수도 있다.
[1] FALSE
[1] TRUE
Warning in sort(x) == sort(z): longer object length is not a multiple
of shorter object length
[1] FALSE
warning message가 번거롭다면 options()
함수의 warn 인수값을 음수로 바꾸면 출력되지 않는다. 그러나 이 방법은 권장하지 않는다. 차라리 다음과 같이 ifelse()
함수를 이용해서 예외처리를 해주면 된다.
[1] FALSE
앞서 집합 포함관계에서도 warning message가 출력되었는데 이와 같이 처리하면 된다.
For attribution, please cite this work as
유충현 (2005, June 22). Dataholic: 집합연산. Retrieved from https://choonghyunryu.github.io/posts/2005-06-22-operation-sets/
BibTeX citation
@misc{유충현2005집합연산, author = {유충현, }, title = {Dataholic: 집합연산}, url = {https://choonghyunryu.github.io/posts/2005-06-22-operation-sets/}, year = {2005} }