# Chapter 3 Set Theory

## 3.1 Sets in Mathematics

Intuitively, we understand the concept of sets. In dictionaries, you will find definitions like a group or collection of things that belong together or resemble one another.

In mathematics, sets have a pretty precise definition:

• A set is a well-defined collection of objects.
• Each object in a set is called an element of the set.
• Two sets are equal if they have exactly the same elements in them.
• A set that contains no elements is called a null set or an empty set.
• If every element in Set A is also in Set B, then Set A is a subset of Set B.

Example: if A is the set of first five charachters of the alphabet, then: A = {a,b,c,d,e}

In R we can create this set as follows.

We can decide on the name of the set. Here, we use SetA.

The two characters “<” and “-” form an arrow pointing to the left. Remember that this arrow consists of two characters!

We combine the characters on the right of the arrow, using the c() function

We then assign this combination to SetA, on the lefthand side.

Once we have defined SetA, we can check if certain elements, like “a” and “f” are elements of the set.

SetA <- c("a","b","c","d","e")
"a" %in% SetA
## [1] TRUE
"f" %in% SetA
## [1] FALSE

Likewise, we can create a set of numbers, from 1 to 100.

You can use arrows pointing to the right, as you see below! But it’s very uncommon to do so. Normally, we use the logic Object <- Created from, rather than Created from -> Object. So, we will do it once and never again, for illustration.

c(1:100) -> SetN
length(SetN)
## [1] 100
88 %in% SetN  # Is 88  an element of our set? [TRUE, it is!]
## [1] TRUE
105 %in%SetN  # Is 105 an element of our set? [FALSE, it is not!]        
## [1] FALSE

## 3.2 Relations between Sets

### 3.2.1 Empty Set

An empty set is a set without elements.

SetEmpty <- NULL
length(SetEmpty)   # the length of an empty set is zero
## [1] 0
"2" %in% SetEmpty  # is 2 part of our empty set?
## [1] FALSE

### 3.2.2 Identical Sets

Apart from the sequence of elements, the two sets below are identical.

All elements of A occur in B, and all elements of B are part of A.

SetA <- c("1","3","4","6")
SetB <- c("1","4","6","3")
SetB %in% SetA
## [1] TRUE TRUE TRUE TRUE
SetA %in% SetB
## [1] TRUE TRUE TRUE TRUE

The overlap between two sets, is called the intersection.

The intersection is graphically displayed below.

All elements that are part of two sets combined (either A, B or both) form the union of the two sets.

In a graph:

The intersect of two sets is written as $$A \cap B$$.

The union of two sets is written as $$A \cup B$$. A little trick to help you remember is that the $$\cup$$ symbol resembles the first character (“u”) of the word “union”.

We can test the differences and similarities using the commands below.

setdiff(SetA, SetB)
## character(0)
setequal(SetA, SetB)
## [1] TRUE
intersect(SetA, SetB)
## [1] "1" "3" "4" "6"

Let’s look at some other examples.

The two sets below are not identical, and contain duplicates.

From the result we see that duplicates are removed! The element “a” appears twice in SetA, but only once in the union of both sets.

SetA <- c("a","a","b","c","d")
SetB <- c("c","c","d","e")
union(SetA, SetB)
## [1] "a" "b" "c" "d" "e"

There are various functions in R that help you detect unique and duplicate cases.

Two of these functions are unique() and duplicated().

Applying unique() to a set, filters out any duplicates.

The function duplicated() indicates, for each element, starting from the first element in the set, if it is the same as any of the preceding elements. Since the first element, by definition, has no predecessor, the indication has to be FALSE.

If, like in SetA, the second element is identical to the first element, it will be TRUE.

Going through the entire set, we generate a list of duplicates: elements with indicator TRUE.

Note that duplication means that the same elements occurs twice or more. That is, triplication, quadruplication, and so on, are just subsets of duplication: elements appearing three times or more, are a subset of elements apperaring twice or more.

We can use the result of duplicated() to index SetA. SetA has five elements (including duplicates). We can index these elements using square brackets [ ].

• For example, SetA[1] returns the first element of SetA.
• And SetA[3:5] returns the third to fifth elements of SetA.
• An alternative way for the latter, would be to use a list of TRUE and FALSE indicators, here c(F,F,T,T,T).

Note that TRUE and FALSE, in this and many other cases, can be abbreviated as T and F. It is considered bad practice in programming. But you will encounter it time and again.

SetA[1]
## [1] "a"
SetA[3:5]
## [1] "b" "c" "d"
SetA[c(F,F,T,T,T)] # Equivalent to previous!
## [1] "b" "c" "d"

Since the duplicated() function produces a list of TRUE and FALSE values, we can use it to index SetA.

However, duplicated() returns TRUE for duplicated elements. If we want to detect unique elements, we use the NOT operator (the exclamation mark, !) to change the TRUE indicators to FALSE, and vice versa.

(SetA)
## [1] "a" "a" "b" "c" "d"
unique(SetA)             # Removes duplicates
## [1] "a" "b" "c" "d"
duplicated(SetA)
## [1] FALSE  TRUE FALSE FALSE FALSE
SetA[!duplicated(SetA)]  # Removes duplicates, in a slightly more complicated way
## [1] "a" "b" "c" "d"

Differences between sets can be checked using the setdiff() function. The function only compares two sets at the time, and the order is important, as you see below!

setdiff(SetA, SetB)  # a en b occur in A, but not in B
## [1] "a" "b"
setdiff(SetB, SetA)  # e occurs in B, but not in A
## [1] "e"

To challenge your skills, we can define the union of sets A and B as follows:

• Elements unique to A, plus:
• Elements unique to B, plus:
• Elements in the interesection of A and B.

We can sort the combination of these three parts alphabetically, and check if indeed the result is equal to what we have defined as the union.

The all() function can be used to see if all elements of one set, are contained by the other.

sort(c(setdiff(SetA, SetB), setdiff(SetB, SetA), intersect(SetB, SetA)))
## [1] "a" "b" "c" "d" "e"
all(sort(c(setdiff(SetA, SetB), setdiff(SetB, SetA), intersect(SetB, SetA))) == union(SetA, SetB))
## [1] TRUE

An alternative to the above code, is to first create an object (say, combi) as the sorted elements of the combined parts. Then, we compare combi to the result of the union() function. It makes our code slightly more readable.

# union, as combination of unique and intersecting elements
combi <- sort(c(setdiff(SetA, SetB), setdiff(SetB, SetA), intersect(SetB, SetA)))
all(combi == union(SetA, SetB)) # check if combi equals the result of union()
## [1] TRUE

Let’s see what happens if duplicated elements of one set, are checked against another set.

All elements of set C (duplicated elements “a”) are part of D.

One element of D, is not contained in A.

SetC <- c("a","a"); SetD <- c("a","b")
SetC %in% SetD
## [1] TRUE TRUE
all(SetC %in% SetD)
## [1] TRUE
SetD %in% SetC
## [1]  TRUE FALSE
all(SetD %in% SetC)
## [1] FALSE

This is what we would expect: “a”, though a duplicated element in setC, occurs in SetD (where “a” only occurs once).

## 3.3 Sets of Numbers

Sets can contain any type of element: characters, binary indicators (like TRUE or FALSE), numbers, and more.

It can be tedious to create sets of characters or words, as you have to do a lot of typing.

Sets of numbers are often easier, especially if it’s a line of numbers, say from 1, 2 .. to 99.

You can use the length() function to return the number of elements (here: numbers).

You can access specific elements using square brackets (indexing). Note that curved brackets () do not work, for indexing. Computers can be very picky.

(SetN <- c(-10:+10)) # Putting the expression between brackets, prints the object in the console!
##  [1] -10  -9  -8  -7  -6  -5  -4  -3  -2  -1   0   1   2   3   4   5   6   7   8
## [20]   9  10
length(SetN)
## [1] 21
SetN[3]
## [1] -8
SetN[3] < SetN[4]
## [1] TRUE

## 3.4 Application of Set Theory, and Sets

You may wonder why all of the above would be of interest to a data scientist like yourself.

There are a least three reasons.

• Logical thinking

First of all, dealing with data and data analysis will force you to think logically.

Even when working with just one data set, say, a (partial) list of employees in your organization who have filled out survey questionnaire, requires you to first assess the quality of the list.

How many employees have filled out the survey twice or more (and what do we do with duplicates, especially if responses by duplicate respondents are inconsistent)? Is the list of (unique) respondents a subset of employees? Is the response rate the same for all departments of the organization? And so on and so forth.

Answers to such questions can be obtained using the tools discussed above, or any out of many alternative tools. But it is the thinking that counts!

• Comparing data sets

One of the starting points in the data mining process, is data understanding.

Often, your analysis is based on data from various sources. Before you start your analysis, you have to understand all sources in depth.

Combining, or merging, data sets from various sources almost without exception reveals errors, inconsistencies and gaps. Applying the basics of set theory will help you in preparing high-quality, analyzable data sets. Or to put it negatively: data science follows the garbage-in-garbage-out principle!

• Probability theory

In some of the modules, we will use probability theory. Concepts like conditional probablitity have close links to set theory. It helps if you’re familiar with the terminologies, and with notations like $$\cup$$ and $$\cap$$.

## 3.5 Exercises

### 3.5.1 Exercise 1

Given are the following sets:

A = {2,4,6,8,10,12,14,16}

B = {1,2,3,4,5,6,7}

C = {3,6,9,12,15,18}

1. A $$\cap$$ B = (Intersection of A and B)
2. A $$\cap$$ C =
3. B $$\cap$$ C =
4. A $$\cap$$ B $$\cap$$ C =
5. A $$\cup$$ B = (Union of A and B)
6. A $$\cup$$ B $$\cup$$ C =

#### 3.5.1.1 Solutions

Let’s first create the sets A, B and C.

We use the seq() function in R. You can find documentation on this function here.

For a sequence of numbers that runs from 2 to 16, in steps of 2, like A, we type seq(2,16,2).

B can be defined as seq(1,7,1), but c(1:7) is shorter. B <- 1:7 would work as well.

A <- seq(2, 16, 2)
B <- c(1:7)
C <- seq(3, 18, 3)
A; B; C  # Prints the three sets
## [1]  2  4  6  8 10 12 14 16
## [1] 1 2 3 4 5 6 7
## [1]  3  6  9 12 15 18
1. A $$\cap$$ B
(intersect(A, B)) # Putting the command between brackets, prints the result
## [1] 2 4 6
1. A $$\cap$$ C
(intersect(A, C)) 
## [1]  6 12
1. B $$\cap$$ C
(intersect(B, C)) 
## [1] 3 6
1. A $$\cap$$ B $$\cap$$ C

intersect(A, B, C) will give an error message, as intersect() only works on two sets!

We can do it in 2 steps; first, we determine the intersection of A and B; followed by the intersection of that result with C!

You can imagine that this is doable for three sets.

But if we were to find the intersection between many sets, then the expression would get very lengthy!

A better alternative is to use the Reduce() function.

Often, you can find solutions to this kind of challenges by just googling.

The Reduce() function, for example, we found on link

intersect(intersect(A,B),C)
## [1] 6
Reduce(intersect, list(A,B,C))
## [1] 6
1. A $$\cup$$ B
sort((union(A, B)))
##  [1]  1  2  3  4  5  6  7  8 10 12 14 16
1. A $$\cup$$ B $$\cup$$ C
sort(Reduce(union, list(A,B, C)))
##  [1]  1  2  3  4  5  6  7  8  9 10 12 14 15 16 18

#### 3.5.1.2Are you in for a challenge?

Which elements are in intersections of sets, but not in all sets?

(AB <- intersect(A,B)) # Pairwise intersection A and B; stored as set AB
## [1] 2 4 6
(AC <- intersect(A,C)) # Id, for A and C
## [1]  6 12
(BC <- intersect(B,C)) # Id, for B and C
## [1] 3 6
(sort(pairs <- Reduce(union, list(AB,AC,BC)))) # All pairwise intersection combined, stored as "pairs"
## [1]  2  3  4  6 12
(trios <- Reduce(intersect, list(A,B,C))) # Elements present in the intersection of all three sets
## [1] 6
sort(setdiff(pairs, trios)) # Elements in pairs, but not in trios
## [1]  2  3  4 12

You see that elements 2, 3, 4 and 12 are in pairwise intersections, but not in the three-way intersection!

Graphically, just to convince you:

### 3.5.2 Exercise 2

Are the following statements true or false?

1. {2,4} $$\subset$$ (A $$\cap$$ B)
2. 6 $$\in$$ (A $$\cap$$ B $$\cap$$ C)
3. {6} $$\subset$$ (A $$\cap$$ B)
4. (A $$\cap$$ B) $$\subset$$ (A $$\cup$$ B)

#### 3.5.2.1 Solutions

1. {2,4} $$\subset$$ (A $$\cap$$ B)
SetTest <- c(2,4)
AB <- intersect(A,B)
all(SetTest %in% AB)
## [1] TRUE
1. 6 $$\in$$ (A $$\cap$$ B $$\cap$$ C)

See below, under c.

1. {6} $$\subset$$ (A $$\cap$$ B)
# In the formulation of c.

SetTest <- c(6)
trios
## [1] 6
all(SetTest %in% trios) # Remember we stored the intersect as "trios"!
## [1] TRUE
# Alternatively (as in b.), define 6 as a single element rather than a set of one element

6 %in% trios
## [1] TRUE
# Note that b. and c. are basically the same!
1. (A $$\cap$$ B) $$\subset$$ (A $$\cup$$ B)

This is true in general. Elements in the intersection of A and B, are by definition part of both A and B. The intersection is therefore a subset of all elements in A or B!

Just to train the formulation of this exercise in R:

all(intersect(A, B) %in% union(A, B))
## [1] TRUE

### 3.5.3 Exercise 3

A = {1,2,3,4,5,6}

B = {5,6}

C = {1,2,5,6}

D = {2,3,4}

E = {2,3,4,5}

Complete the statement with one of the symbols:

• $$\in$$ (element of)
• $$\notin$$ (not an element of)
• $$\subset$$ (subset of)
• $$\supset$$ (superset; if A is subset of B, then B is superset of A)
• $$\cap$$ (intersection)
• $$\cup$$
1. B….C
2. B….C = B
3. B….C = C
4. B….D = 0 (empty set)
5. C….D = A
6. D….E = D
7. 4….C $$\cap$$ B
8. D….E….A

#### 3.5.3.1 Solutions

Use reason to answer each of the questions!

As an additional challenge, formulate the sets in R, and use any of the commands introduced in this chapter to check your answer!

1. $$\subset$$ (B is obviously a subset of C, as all elements of B are also in C)
2. $$\cap$$ (the intersect of B and C, is equal to B, as B is a subset of B)
3. $$\cup$$ (the combined elements of B and C, are equal to C, as C is a superset of B)
4. $$\cap$$ (as B and D have no elements in common, the interesect is the empty set)
5. $$\cup$$ (all elements of C and D combined, match A)
6. $$\cap$$ or $$\subset$$
7. $$\notin$$ (4 is not part of the intersection of B and C; it is not even part of the union of B and C)
8. $$\subset$$ (D is a subset of E, which in turn is a subset of A; you can conclude that therefore D is a subset of A)

Working with data files (in data science) requires logical thinking. Set theory is a good exercise in logical thinking!

### 3.5.4 Exercise 4

Consider the following sets.

• A = {x | x is an even number and x<20; x is a positive natural number}
• B = {x | x is a multiple of 3 and x<20; x is a positive natural number}
• C = {x | x is an odd numbber and x<20; x is a positive natural number}

This looks cryptic.

Set A, for example, reads like the set of numbers x conditioned by the following rules. x is:

• a positive natural number (1, 2, 3 to infinity)
• smaller than 20, and
• divisible by 2.

We can enumerate these numbers easily: 2, 4, 6 .. up to 18.

Set B then is 3, 6, 9 .. up to 18.

And Set C is 1, 3, 5 .. up to 19.

Determine:

1. A $$\cap$$ B
2. A $$\cap$$ B $$\cap$$ C
3. A $$\cup$$ B $$\cup$$ C

Again, create the sets in R and use the proper functions to get the solutions!

#### 3.5.4.1 Solutions

1. {6, 12, 18}
2. 0 (empty set)
3. {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19}
(SetA <- seq(2,18,2)) 
## [1]  2  4  6  8 10 12 14 16 18
(SetB <- seq(3,18,3))
## [1]  3  6  9 12 15 18
(SetC <- seq(1,19,2))
##  [1]  1  3  5  7  9 11 13 15 17 19
intersect(SetA,SetB) # Answer a
## [1]  6 12 18
Reduce(intersect, list(SetA,SetB,SetC)) # Answer B
## numeric(0)
Reduce(union, list(SetA,SetB,SetC)) # Answer C
##  [1]  2  4  6  8 10 12 14 16 18  3  9 15  1  5  7 11 13 17 19