generated from r4ds/bookclub-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path03_logical-vectors.Rmd
171 lines (103 loc) · 3.11 KB
/
03_logical-vectors.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# Logical vectors
**Learning objectives:**
- Introduction to logical vector.
- Comparing elements:
* Integer
* Double precision float
- Logical operations
## Creating logical vectors {-}
```{r}
c(TRUE, FALSE, NA, TRUE, FALSE)
sample(c(TRUE, FALSE),
10,
replace = TRUE, # you get an error if omited
prob = c(.8, .2))
```
## Comparing elements (1)
We have the usual binary operators : `<` , `>`, `<=` , `>=`, `==` and `!=`
They operate elementwise:
```{r}
c(1, 2, 3, 4) == c(2, 2, 3, 8)
```
And R apply the *recycle rule*:
```{r}
3 < 1:5
```
## Comparing elements, NA, NaN, Inf (2)
Testing equality on NA is not correct: What does "I do not know" `==` "I do not know" could mean. We should use the function `is.na()`.
We should also use `is.finite`, and `is.nan` (all of them are vectorized)
## Dealing with integer and floating point numbers
- Doing math with integer is always safe
```{r}
.Machine$integer.max
# but you can still overflow:
# note: it is a warning not an error
.Machine$integer.max + 1L
```
- Floating point number are "limited": 8 bytes
```{r}
print(0.1234567891123456789012, digits = 22)
```
Hence:
```{r}
0.1 + 0.2 == 0.3
```
What can we do!
- `round` is an usual trick
- the author likes `abs(x - y) < very_small_number`
```{r}
abs(sin(pi) - 0) < 2^-26
```
## Logical operations
### Vectorized logical operations:
`TRUE` and `FALSE` can also be a result of a "predicate":
`==` and `>` (and co.) only accept two arguments (binary operators):
We need to use logical operators (`help("Logic")`).
Logical operators:
* `!` not (Unary)
* `&` and: are both true
* `|` or: at least one true
* `xor` exclusive-or: one and only one is true
(We will see their scalar counter part in chapter 8)
Those operators have lower precedence than the arithmetic so they are quite intuitive (except maybe `!`)
### missingness
- `NA` | `TRUE` -> `TRUE` (this one is easy)
- `NA` | `FALSE` -> `NA` because it depend on what `NA` could be
(in doubt build a quick *truth tables*)
### Aggregating with all, any and sum
- `all()` test if all elements match
- `any()` test if at least one match
- `sum()` use the trick that `FALSE` is `0` and `TRUE` is `1`
```{r}
sum(runif(10000) >= .2)
```
### Simplify predicates
You should think about it!
* a > b | a <= b : this one is obvious (but I could have done it!)
some are less obvious.
## Selecting elements based on a condition: ifelse
We will see `if ... else ...` later
ifelse follow this syntax:
ifelse(l, t, f): ie if `l` is `TRUE` do `t` / if `l` is FALSE do `f`
```{r}
z <- rnorm(6)
ifelse(z >= 0, z, - z ) # yup abs(z)
```
it applies the recycle rules:
```{r}
x <- rnorm(6)
ifelse(x > 0, x^2, 0)
```
Important: all elements are evaluated before knowing which are selected! (that explain we have a warning sometimes instead of an error)
## Good resource:
Julia's zine:
https://store.wizardzines.com/products/how-integers-and-floats-work
## Meeting Videos {-}
### Cohort 1 {-}
`r knitr::include_url("https://www.youtube.com/embed/URL")`
<details>
<summary> Meeting chat log </summary>
```
LOG
```
</details>