html.json (18096B)
1 { 2 "hash": "d7ca12190e1edb91ae8731c452ae68f5", 3 "result": { 4 "engine": "knitr", 5 "markdown": "---\nengine: knitr\ntitle: Subsetting\n---\n\n## Learning objectives:\n\n- Select multiple elements from a vector with `[`\n- Select single elements from a vector with `[[` and `$`\n- Assign to subsets of vectors\n- Use subsetting to expand data\n\n# Selecting multiple elements\n\n## 1. Positive integers return elements at specified positions\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- c(1.1, 2.2, 3.3, 4.4) # decimal = original position\nx\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 3.3 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(4, 1)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 4.4 1.1\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(1, 1, 1)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 1.1 1.1\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(1.9999)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1\n```\n\n\n:::\n:::\n\n\nReals *truncate* to integers.\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(1.0001, 1.9999)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 1.1\n```\n\n\n:::\n:::\n\n\n## 2. Negative integers remove specified elements\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[-c(1, 3)] # same as x[c(-1, -3)] or x[c(2, 4)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 2.2 4.4\n```\n\n\n:::\n:::\n\n\n## 2b. Mixing negative and positive integers throws an error\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(-1, 3)]\n```\n\n::: {.cell-output .cell-output-error}\n\n```\n#> Error in x[c(-1, 3)]: only 0's may be mixed with negative subscripts\n```\n\n\n:::\n:::\n\n\n## 2c. Zeros ignored with other ints \n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(-1, 0)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 2.2 3.3 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(-1, 0, 0, 0, 0, 0 ,0 ,0)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 2.2 3.3 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(1, 0, 2, 0, 3, 0)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 3.3\n```\n\n\n:::\n:::\n\n\n\n## 3. Logical vectors select specified elements\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(TRUE, TRUE, FALSE, TRUE)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\nx[x < 3]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2\n```\n\n\n:::\n\n```{.r .cell-code}\ncond <- x > 2.5\nx[cond]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 3.3 4.4\n```\n\n\n:::\n:::\n\n\n## 3b. Shorter element are recycled to higher length\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[FALSE]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> numeric(0)\n```\n\n\n:::\n\n```{.r .cell-code}\nx[TRUE]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 3.3 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\nx[c(FALSE, TRUE)] # equivalent to: x[c(FALSE, TRUE, FALSE, TRUE)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 2.2 4.4\n```\n\n\n:::\n:::\n\n\n- Easy to understand if x or y is 1, best to avoid other lengths\n\n## 3c. NA index returns NA\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(NA, TRUE, NA, TRUE)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] NA 2.2 NA 4.4\n```\n\n\n:::\n:::\n\n## 3d. Extra TRUE index returns NA\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[c(FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 2.2 3.3 4.4 NA NA\n```\n\n\n:::\n\n```{.r .cell-code}\nx[1:5]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 3.3 4.4 NA\n```\n\n\n:::\n:::\n\n\n## 4. Indexing with nothing returns original vector\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1.1 2.2 3.3 4.4\n```\n\n\n:::\n:::\n\n\n## 5. Indexing with just 0 returns 0-length vector (with class)\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx[0]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> numeric(0)\n```\n\n\n:::\n\n```{.r .cell-code}\nletters[0]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> character(0)\n```\n\n\n:::\n:::\n\n\n## 6. Indexing with character vector returns element of named vector\n\n\n::: {.cell}\n\n```{.r .cell-code}\n(y <- setNames(x, letters[1:4]))\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> a b c d \n#> 1.1 2.2 3.3 4.4\n```\n\n\n:::\n\n```{.r .cell-code}\ny[c(\"d\", \"b\", \"a\")]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> d b a \n#> 4.4 2.2 1.1\n```\n\n\n:::\n\n```{.r .cell-code}\ny[c(\"a\", \"a\", \"a\")]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> a a a \n#> 1.1 1.1 1.1\n```\n\n\n:::\n:::\n\n\n## 6b. Names must be exact for `[`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nz <- c(abc = 1, def = 2)\nz\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> abc def \n#> 1 2\n```\n\n\n:::\n\n```{.r .cell-code}\nz[c(\"a\", \"d\")]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> <NA> <NA> \n#> NA NA\n```\n\n\n:::\n:::\n\n\n## Subsetting a list with `[` returns a list\n\n\n::: {.cell}\n\n```{.r .cell-code}\nmy_list <- list(a = c(T, F), b = letters[5:15], c = 100:108)\nmy_list\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $a\n#> [1] TRUE FALSE\n#> \n#> $b\n#> [1] \"e\" \"f\" \"g\" \"h\" \"i\" \"j\" \"k\" \"l\" \"m\" \"n\" \"o\"\n#> \n#> $c\n#> [1] 100 101 102 103 104 105 106 107 108\n```\n\n\n:::\n\n```{.r .cell-code}\nmy_list[c(\"a\", \"b\")]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $a\n#> [1] TRUE FALSE\n#> \n#> $b\n#> [1] \"e\" \"f\" \"g\" \"h\" \"i\" \"j\" \"k\" \"l\" \"m\" \"n\" \"o\"\n```\n\n\n:::\n:::\n\n\n## Lists use same rules for `[`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nmy_list[2:3]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $b\n#> [1] \"e\" \"f\" \"g\" \"h\" \"i\" \"j\" \"k\" \"l\" \"m\" \"n\" \"o\"\n#> \n#> $c\n#> [1] 100 101 102 103 104 105 106 107 108\n```\n\n\n:::\n\n```{.r .cell-code}\nmy_list[c(TRUE, FALSE, TRUE)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $a\n#> [1] TRUE FALSE\n#> \n#> $c\n#> [1] 100 101 102 103 104 105 106 107 108\n```\n\n\n:::\n:::\n\n\n## Matrices & arrays take multidimensional indices\n\n\n::: {.cell}\n\n```{.r .cell-code}\na <- matrix(1:9, nrow = 3)\na\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [,1] [,2] [,3]\n#> [1,] 1 4 7\n#> [2,] 2 5 8\n#> [3,] 3 6 9\n```\n\n\n:::\n\n```{.r .cell-code}\na[1:2, 2:3] # rows, columns\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [,1] [,2]\n#> [1,] 4 7\n#> [2,] 5 8\n```\n\n\n:::\n:::\n\n\n## Matrices & arrays can accept character, logical, etc\n\n\n::: {.cell}\n\n```{.r .cell-code}\ncolnames(a) <- c(\"A\", \"B\", \"C\")\na[c(TRUE, TRUE, FALSE), c(\"B\", \"A\")] # a[1:2, 2:1]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> B A\n#> [1,] 4 1\n#> [2,] 5 2\n```\n\n\n:::\n:::\n\n\n## Matrices & arrays are also vectors\n\n\n::: {.cell}\n\n```{.r .cell-code}\nvals <- outer(1:5, 1:5, FUN = \"paste\", sep = \",\") # All chr combos of 1:5\nvals\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [,1] [,2] [,3] [,4] [,5] \n#> [1,] \"1,1\" \"1,2\" \"1,3\" \"1,4\" \"1,5\"\n#> [2,] \"2,1\" \"2,2\" \"2,3\" \"2,4\" \"2,5\"\n#> [3,] \"3,1\" \"3,2\" \"3,3\" \"3,4\" \"3,5\"\n#> [4,] \"4,1\" \"4,2\" \"4,3\" \"4,4\" \"4,5\"\n#> [5,] \"5,1\" \"5,2\" \"5,3\" \"5,4\" \"5,5\"\n```\n\n\n:::\n\n```{.r .cell-code}\nvals[c(4, 15)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"4,1\" \"5,3\"\n```\n\n\n:::\n\n```{.r .cell-code}\na[a > 5]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 6 7 8 9\n```\n\n\n:::\n:::\n\n\n## Data frames subset list-like with single index\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndf <- data.frame(x = 1:3, y = 3:1, z = letters[1:3])\ndf[1:2]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x y\n#> 1 1 3\n#> 2 2 2\n#> 3 3 1\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[c(\"x\", \"z\")]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x z\n#> 1 1 a\n#> 2 2 b\n#> 3 3 c\n```\n\n\n:::\n:::\n\n\n## Data frames subset matrix-like with multiple indices\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndf[1:2, c(\"x\", \"z\")] # rows, columns\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x z\n#> 1 1 a\n#> 2 2 b\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[df$x == 2, ] # matching rows, all columns\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x y z\n#> 2 2 2 b\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[, c(\"x\", \"z\")] # equivalent to no ,\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x z\n#> 1 1 a\n#> 2 2 b\n#> 3 3 c\n```\n\n\n:::\n:::\n\n\n## Subsetting a tibble with `[` returns a tibble\n\n\n::: {.cell}\n\n```{.r .cell-code}\ntbl <- tibble::as_tibble(df)\ndf[, 1]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1 2 3\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[, 1, drop = FALSE] # Prevent errors\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x\n#> 1 1\n#> 2 2\n#> 3 3\n```\n\n\n:::\n\n```{.r .cell-code}\ntbl[, 1]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> # A tibble: 3 × 1\n#> x\n#> <int>\n#> 1 1\n#> 2 2\n#> 3 3\n```\n\n\n:::\n:::\n\n\n# Selecting a single element\n\n## `[[` selects a single element\n\n:::: columns\n\n::: column\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- list(1:3, \"a\", 4:6)\nx[1]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [[1]]\n#> [1] 1 2 3\n```\n\n\n:::\n\n```{.r .cell-code}\nclass(x[1])\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"list\"\n```\n\n\n:::\n\n```{.r .cell-code}\nx[[1]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1 2 3\n```\n\n\n:::\n\n```{.r .cell-code}\nclass(x[[1]])\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"integer\"\n```\n\n\n:::\n\n```{.r .cell-code}\nx[[1]][[1]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1\n```\n\n\n:::\n:::\n\n:::\n\n::: column\n\n\n:::\n\n::::\n\n## `$` is shorthand for `[[..., exact = FALSE]]`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- list(abc = 1)\nx$abc\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1\n```\n\n\n:::\n\n```{.r .cell-code}\nx$a\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1\n```\n\n\n:::\n\n```{.r .cell-code}\nx[[\"a\"]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n\n```{.r .cell-code}\nx[[\"a\", exact = FALSE]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1\n```\n\n\n:::\n\n```{.r .cell-code}\noptions(warnPartialMatchDollar = TRUE)\nx$a\n```\n\n::: {.cell-output .cell-output-stderr}\n\n```\n#> Warning in x$a: partial match of 'a' to 'abc'\n```\n\n\n:::\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1\n```\n\n\n:::\n:::\n\n\n## Behavior for missing-ish indices is inconsistent\n\n\n::: {.cell}\n\n```{.r .cell-code}\na <- c(a = 1L, b = 2L)\nlst <- list(a = 1:2)\n\n# Errors:\n# a[[NULL]]\n# lst[[NULL]]\n# a[[5]]\n# lst[[5]]\n# a[[\"c\"]]\n# a[[NA]]\n\nlst[[\"c\"]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n\n```{.r .cell-code}\nlst[[NA]]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n:::\n\n\n## `purrr::pluck()` and `purrr::chuck()` provide consistent wrappers\n\n- `purrr::pluck()` always returns `NULL` or `.default` for (non-`NULL`) missing\n- `purrr::chuck()` always throws error\n\n\n::: {.cell}\n\n```{.r .cell-code}\npurrr::pluck(a, 5)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n\n```{.r .cell-code}\npurrr::pluck(a, \"c\")\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n\n```{.r .cell-code}\npurrr::pluck(lst, 5)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n\n```{.r .cell-code}\npurrr::pluck(lst, \"c\")\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> NULL\n```\n\n\n:::\n:::\n\n\n## S4 has two additional subsetting operators\n\n- `@` equivalent to `$` (but error if bad)\n- `slot()` equivalent to `[[`\n\nMore in Chapter 15\n\n# Subsetting and assignment\n\n## Can assign to position with `[`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- 1:5\nx[1:2] <- c(101, 102)\nx\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 101 102 3 4 5\n```\n\n\n:::\n\n```{.r .cell-code}\nx[1:3] <- 1:2\nx\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1 2 1 4 5\n```\n\n\n:::\n:::\n\n\n## Remove list component with `NULL`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- list(a = 1, b = 2)\nx[[\"b\"]] <- NULL\nx\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $a\n#> [1] 1\n```\n\n\n:::\n:::\n\n\n## Use `list(NULL)` to add `NULL`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- list(a = 1, b = 2)\nx[[\"b\"]] <- list(NULL)\nx\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> $a\n#> [1] 1\n#> \n#> $b\n#> $b[[1]]\n#> NULL\n```\n\n\n:::\n:::\n\n\n## Subset with nothing to retain shape\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndf <- data.frame(a = 1:3, b = 1:3)\ndf[] <- \"a\"\ndf\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> a b\n#> 1 a a\n#> 2 a a\n#> 3 a a\n```\n\n\n:::\n\n```{.r .cell-code}\ndf <- \"a\"\ndf\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"a\"\n```\n\n\n:::\n:::\n\n\n# Applications\n\n## Use a lookup vector and recycling rules to translate values\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- c(\"b\", \"g\", \"x\", \"g\", \"g\", \"b\")\nlookup <- c(b = \"blue\", g = \"green\", x = NA)\nlookup[x]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> b g x g g b \n#> \"blue\" \"green\" NA \"green\" \"green\" \"blue\"\n```\n\n\n:::\n\n```{.r .cell-code}\nunname(lookup[x])\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"blue\" \"green\" NA \"green\" \"green\" \"blue\"\n```\n\n\n:::\n:::\n\n\n## Use a lookup table to generate rows of data\n\n\n::: {.cell}\n\n```{.r .cell-code}\ninfo <- data.frame(\n code = c(\"b\", \"g\", \"x\"),\n color = c(\"blue\", \"green\", NA),\n other_thing = 3:1\n)\nmatch(x, info$code) # Indices of info$code in x\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1 2 3 2 2 1\n```\n\n\n:::\n\n```{.r .cell-code}\ninfo[match(x, info$code), ]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> code color other_thing\n#> 1 b blue 3\n#> 2 g green 2\n#> 3 x <NA> 1\n#> 2.1 g green 2\n#> 2.2 g green 2\n#> 1.1 b blue 3\n```\n\n\n:::\n:::\n\n\n## Sort with `order()`\n\n\n::: {.cell}\n\n```{.r .cell-code}\nx <- c(\"b\", \"c\", \"a\")\norder(x)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 3 1 2\n```\n\n\n:::\n\n```{.r .cell-code}\nx[order(x)]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] \"a\" \"b\" \"c\"\n```\n\n\n:::\n\n```{.r .cell-code}\ndf <- data.frame(b = 3:1, a = 1:3)\ndf[order(df$b), ]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> b a\n#> 3 1 3\n#> 2 2 2\n#> 1 3 1\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[, order(names(df))]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> a b\n#> 1 1 3\n#> 2 2 2\n#> 3 3 1\n```\n\n\n:::\n:::\n\n\n## Expand counts\n\n\n::: {.cell}\n\n```{.r .cell-code}\ndf <- data.frame(x = c(2, 4, 1), y = c(9, 11, 6), n = c(3, 5, 1))\nrep(1:nrow(df), df$n)\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> [1] 1 1 1 2 2 2 2 2 3\n```\n\n\n:::\n\n```{.r .cell-code}\ndf[rep(1:nrow(df), df$n), ]\n```\n\n::: {.cell-output .cell-output-stdout}\n\n```\n#> x y n\n#> 1 2 9 3\n#> 1.1 2 9 3\n#> 1.2 2 9 3\n#> 2 4 11 5\n#> 2.1 4 11 5\n#> 2.2 4 11 5\n#> 2.3 4 11 5\n#> 2.4 4 11 5\n#> 3 1 6 1\n```\n\n\n:::\n:::\n\n\n## Ran out of time to make slides for\n\nIdeally a future cohort should expand these:\n\n- Remove df columns with `setdiff()`\n- Logically subset rows `df[df$col > 5, ]`\n- The next slide about `which()`\n\n## Boolean algebra versus sets (logical and integer)\n\n- `which()` gives the indices of a Boolean vector\n\n\n::: {.cell}\n\n```{.r .cell-code}\n(x1 <- 1:10 %% 2 == 0) # 1-10 divisible by 2\n# [1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE\n(x2 <- which(x1))\n# [1] 2 4 6 8 10\n(y1 <- 1:10 %% 5 == 0) # 1-10 divisible by 5\n# [1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE TRUE\n(y2 <- which(y1))\n# [1] 5 10\nx1 & y1\n# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE\n```\n:::\n\n", 6 "supporting": [ 7 "04_files" 8 ], 9 "filters": [ 10 "rmarkdown/pagebreak.lua" 11 ], 12 "includes": { 13 "include-after-body": [ 14 "\n<script>\n // htmlwidgets need to know to resize themselves when slides are shown/hidden.\n // Fire the \"slideenter\" event (handled by htmlwidgets.js) when the current\n // slide changes (different for each slide format).\n (function () {\n // dispatch for htmlwidgets\n function fireSlideEnter() {\n const event = window.document.createEvent(\"Event\");\n event.initEvent(\"slideenter\", true, true);\n window.document.dispatchEvent(event);\n }\n\n function fireSlideChanged(previousSlide, currentSlide) {\n fireSlideEnter();\n\n // dispatch for shiny\n if (window.jQuery) {\n if (previousSlide) {\n window.jQuery(previousSlide).trigger(\"hidden\");\n }\n if (currentSlide) {\n window.jQuery(currentSlide).trigger(\"shown\");\n }\n }\n }\n\n // hookup for slidy\n if (window.w3c_slidy) {\n window.w3c_slidy.add_observer(function (slide_num) {\n // slide_num starts at position 1\n fireSlideChanged(null, w3c_slidy.slides[slide_num - 1]);\n });\n }\n\n })();\n</script>\n\n" 15 ] 16 }, 17 "engineDependencies": {}, 18 "preserve": {}, 19 "postProcess": true 20 } 21 }