## 2.3 常用函数

### 2.3.1 条件判断

dplyr::if_else()相比于base::ifelse,if_else输出类型更为严格，无论TRUEFALSE输出类型一致，这样计算速度更快。

dplyr::if_else()参数:

if_else(condition, true, false, missing = NULL)
x <- sample(1:10,5)
if_else(x>5,"大于五","小于等于五",missing = "空值")
#> [1] "大于五"     "大于五"     "大于五"     "大于五"     "小于等于五"

ifelse不同的是，if_else保留类型

x <- factor(sample(letters[1:5], 10, replace = TRUE))
ifelse(x %in% c("a", "b", "c"), x, factor(NA))
#>  [1] NA  2  1 NA  1  2  3  1  1  2
if_else(x %in% c("a", "b", "c"), x, factor(NA))
#>  [1] <NA> b    a    <NA> a    b    c    a    a    b
#> Levels: a b c d e

data.table::fifelse()功能相似

### 2.3.2 case_when

x <- 1:50
case_when(
x %% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
TRUE ~ as.character(x)
)
#>  [1] "1"         "2"         "3"         "4"         "fizz"      "6"
#>  [7] "buzz"      "8"         "9"         "fizz"      "11"        "12"
#> [13] "13"        "buzz"      "fizz"      "16"        "17"        "18"
#> [19] "19"        "fizz"      "buzz"      "22"        "23"        "24"
#> [25] "fizz"      "26"        "27"        "buzz"      "29"        "fizz"
#> [31] "31"        "32"        "33"        "34"        "fizz buzz" "36"
#> [37] "37"        "38"        "39"        "fizz"      "41"        "buzz"
#> [43] "43"        "44"        "fizz"      "46"        "47"        "48"
#> [49] "buzz"      "fizz"
Dates <- as.Date(c('2018-10-01', '2018-10-02', '2018-10-03','2018-10-04'))
case_when(
Dates == '2018-10-01' ~ Dates - 1,
Dates == '2018-10-02' ~ Dates + 1,
Dates == '2018-10-03' ~ Dates + 2,
TRUE ~ Dates
)
#> [1] "2018-09-30" "2018-10-03" "2018-10-05" "2018-10-04"

starwars %>%
mutate(性别 = case_when(
sex == "male" ~ "雄性",
sex == "female" ~ "雌性",
sex == "hermaphroditic" ~ "雌雄同体",
TRUE ~ "无"
)) %>%
pull(性别) %>%
table()
#> .
#>     雌性 雌雄同体       无     雄性
#>       16        1       10       60

pull()功能与　data$．类似，为了在管道中使用设计 ### 2.3.3 计数函数 • 计数 count()函数用来计数。下面两种表达方式等价。 df %>% count(a, b) # same above df %>% group_by(a, b) %>% summarise(n = n()) starwars %>% count(species) #> # A tibble: 38 x 2 #> species n #> <chr> <int> #> 1 Aleena 1 #> 2 Besalisk 1 #> 3 Cerean 1 #> 4 Chagrian 1 #> 5 Clawdite 1 #> 6 Droid 6 #> # ... with 32 more rows # same above 等价 starwars %>% group_by(species) %>% summarise(n = n()) #> # A tibble: 38 x 2 #> species n #> <chr> <int> #> 1 Aleena 1 #> 2 Besalisk 1 #> 3 Cerean 1 #> 4 Chagrian 1 #> 5 Clawdite 1 #> 6 Droid 6 #> # ... with 32 more rows • 非重复计数 n_distinct()length(unique(x))等价，但是更快更简洁。当我们需要给门店或订单之类数据去重计算时采用该函数。 x <- sample(1:10, 1e5, rep = TRUE) length(unique(x)) #> [1] 10 n_distinct(x) #> [1] 10 ### 2.3.4 排序函数 dplyr共六种排序函数，模仿SQL2003中的排名函数。 • row_number():等于 rank(ties.method = “first”) • min_rank(): 等于 rank(ties.method = “min”) • dense_rank(): 与min_rank()相似,但是没有间隔 • percent_rank():返回0，1之间，通过min_rank()返回值缩放至[0,1] x <- c(5, 1, 3, 2, 2, NA) row_number(x) #> [1] 5 1 4 2 3 NA min_rank(x) #> [1] 5 1 4 2 2 NA dense_rank(x) #> [1] 4 1 3 2 2 NA percent_rank(x) #> [1] 1.00 0.00 0.75 0.25 0.25 NA cume_dist(x) #> [1] 1.0 0.2 0.8 0.6 0.6 NA ### 2.3.5 提取向量 该系列函数是对[[的包装，方便提取向量。 nth(x, n, order_by = NULL, default = default_missing(x)) first(x, order_by = NULL, default = default_missing(x)) last(x, order_by = NULL, default = default_missing(x)) x <- 1:10 y <- 10:1 first(x) #> [1] 1 last(y) #> [1] 1 nth(x, 1) #> [1] 1 nth(x, 5) #> [1] 5 ### 2.3.6 slice 系列 slice()函数让我们按照行数切片，让我们筛选，删除、重复某些行。和 python 中的 pandas 库的切片类似。 slice()共有如下几组函数： • slice_head() 和 slice_tail()，选着头和尾行 。 • slice_sample() 随机选择行。 • slice_min() 和 slice_max() 按照变量的最低值和最高值选择行。 如果用于 slice() 系列函数的数据集.data 是被 group_by() 过，那每个函数将作用在每一组上。例如，按照商品大类取每个商品大类前五的商品。 dt %>% group_by(商品大类) %>% slice_head(n = 5) #### 2.3.6.1 函数用法 slice(.data, ..., .preserve = FALSE) slice_head(.data, ..., n, prop) slice_tail(.data, ..., n, prop) slice_min(.data, order_by, ..., n, prop, with_ties = TRUE) slice_max(.data, order_by, ..., n, prop, with_ties = TRUE) slice_sample(.data, ..., n, prop, weight_by = NULL, replace = FALSE) #### 2.3.6.2 参数解释 .data: 一个 data.frame , data frame extension (tibble) …: 必须是整数，如果是正数将保留，负值将删除。提供的值超过行数的将会被忽略 .preserve :默认为FALSE,根据结果数据重新计算分组结构，否则保持原样分组 n,p: 提供要选择的行数 n,或行的比列比如 prop = 0.4，如果都未提供则默认n = 1 order_by: 要排序的变量或者是被函数作用的变量 with_ties: 针对 _min 或 _max 函数，相等时候是否强制输出指定行数。 weight_by: 抽样的权重 replace: 是否允许重复抽样，默认为FALSE #### 2.3.6.3 slice 案例 • slice() # 筛选第一行 mtcars %>% slice(1L) #> # A tibble: 1 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 # 筛选最后一行 mtcars %>% slice(n()) #> # A tibble: 1 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2 # 筛选5至最后一行 mtcars %>% slice(5:n()) #> # A tibble: 28 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 #> 2 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 #> 3 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 #> 4 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 #> 5 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 #> 6 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 #> # ... with 22 more rows # 删除前面四行 slice(mtcars, -(1:4)) #> # A tibble: 28 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 #> 2 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 #> 3 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 #> 4 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 #> 5 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 #> 6 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 #> # ... with 22 more rows • slice_head slice_tail # 基于现有顺序筛选前面行或最后行 mtcars %>% slice_head(n = 5) #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 #> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 #> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 #> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 #> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 mtcars %>% slice_tail(n = 5) #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2 #> 2 15.8 8 351 264 4.22 3.17 14.5 0 1 5 4 #> 3 19.7 6 145 175 3.62 2.77 15.5 0 1 5 6 #> 4 15 8 301 335 3.54 3.57 14.6 0 1 5 8 #> 5 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2 • slice_min slice_max # 基于变量筛选 mtcars %>% slice_min(mpg, n = 5) #最小的五行 #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4 #> 2 10.4 8 460 215 3 5.42 17.8 0 0 3 4 #> 3 13.3 8 350 245 3.73 3.84 15.4 0 0 3 4 #> 4 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4 #> 5 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4 mtcars %>% slice_max(mpg, n = 5) #最大的五行 #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1 #> 2 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1 #> 3 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2 #> 4 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2 #> 5 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1 # slice_min()可能返回更多行，通过with_ties参数控制 mtcars %>% slice_min(cyl, n = 1) #> # A tibble: 11 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 #> 2 24.4 4 147. 62 3.69 3.19 20 1 0 4 2 #> 3 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2 #> 4 32.4 4 78.7 66 4.08 2.2 19.5 1 1 4 1 #> 5 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2 #> 6 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1 #> # ... with 5 more rows mtcars %>% slice_min(cyl, n = 1, with_ties = FALSE) #> # A tibble: 1 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 • slice_sample 在数据集中抽样，通过 replace 参数控制是否可以重复。 mtcars %>% slice_sample(n = 5) #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4 #> 2 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4 #> 3 30.4 4 75.7 52 4.93 1.62 18.5 1 1 4 2 #> 4 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1 #> 5 13.3 8 350 245 3.73 3.84 15.4 0 0 3 4 mtcars %>% slice_sample(n = 5, replace = TRUE) #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21.5 4 120. 97 3.7 2.46 20.0 1 0 3 1 #> 2 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4 #> 3 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4 #> 4 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3 #> 5 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 weight_by 参数调整抽样权重 # 重量大的会更容易抽到 mtcars %>% slice_sample(weight_by = wt, n = 5) #> # A tibble: 5 x 11 #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2 #> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 #> 3 15.5 8 318 150 2.76 3.52 16.9 0 0 3 2 #> 4 21 6 160 110 3.9 2.62 16.5 0 1 4 4 #> 5 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4 • 分组操作 df <- tibble( group = rep(c("a", "b", "c"), c(1, 2, 4)), x = runif(7) ) df %>% group_by(group) %>% slice_head(n = 2) #> # A tibble: 5 x 2 #> # Groups: group [3] #> group x #> <chr> <dbl> #> 1 a 0.810 #> 2 b 0.802 #> 3 b 0.860 #> 4 c 0.344 #> 5 c 0.683 # 注意体会使用prop参数时的差异 df %>% group_by(group) %>% slice_head(prop = 0.4) #仅c组返回一个，因为c组3个数字的 40%的前面还有数 #> # A tibble: 1 x 2 #> # Groups: group [1] #> group x #> <chr> <dbl> #> 1 c 0.344 df %>% group_by(group) %>% slice_head(prop = 0.5) # 因为a组只有一个数字，前50%位没有数字 #> # A tibble: 3 x 2 #> # Groups: group [2] #> group x #> <chr> <dbl> #> 1 b 0.802 #> 2 c 0.344 #> 3 c 0.683 ### 2.3.7 group 系列 group 系列函数包含 group_by(),group_map(), group_nest(), group_split(), group_trim()等。 其中我常用group_by(),group_split()两个函数。group_by()是我们熟悉的动词，大部分数据操作中的分组操作由它完成。 • group_by() #group_by()不会改变数据框 by_cyl <- mtcars %>% group_by(cyl) by_cyl #> # A tibble: 32 x 11 #> # Groups: cyl [3] #> mpg cyl disp hp drat wt qsec vs am gear carb #> <dbl> <int> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21 6 160 110 3.9 2.62 16.5 0 1 4 4 #> 2 21 6 160 110 3.9 2.88 17.0 0 1 4 4 #> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 4 1 #> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1 #> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2 #> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1 #> # ... with 26 more rows # It changes how it acts with the other dplyr verbs: by_cyl %>% summarise( disp = mean(disp), hp = mean(hp) ) #> # A tibble: 3 x 3 #> cyl disp hp #> <int> <dbl> <dbl> #> 1 4 105. 82.6 #> 2 6 183. 122. #> 3 8 353. 209. # group_by中可以添加计算字段 即mutate操作 mtcars %>% group_by(vsam = vs + am) %>% group_vars() #> [1] "vsam" － group_split() 目前该函数是实验性的，group_split() 功能与 base::split()相似，按照数据集的分组变量切割数据集。如下，将 iris 数据集按照 Species 分组并切割成长度为3的列表，每个子元素是 Species 变量的子数据集。Species 变量包含setosaversicolorvirginica三种情况。 ir <- iris %>% group_by(Species) group_split(ir) #> <list_of< #> tbl_df< #> Sepal.Length: double #> Sepal.Width : double #> Petal.Length: double #> Petal.Width : double #> Species : factor<fb977> #> > #> >[3]> #> [[1]] #> # A tibble: 50 x 5 #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> <dbl> <dbl> <dbl> <dbl> <fct> #> 1 5.1 3.5 1.4 0.2 setosa #> 2 4.9 3 1.4 0.2 setosa #> 3 4.7 3.2 1.3 0.2 setosa #> 4 4.6 3.1 1.5 0.2 setosa #> 5 5 3.6 1.4 0.2 setosa #> 6 5.4 3.9 1.7 0.4 setosa #> # ... with 44 more rows #> #> [[2]] #> # A tibble: 50 x 5 #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> <dbl> <dbl> <dbl> <dbl> <fct> #> 1 7 3.2 4.7 1.4 versicolor #> 2 6.4 3.2 4.5 1.5 versicolor #> 3 6.9 3.1 4.9 1.5 versicolor #> 4 5.5 2.3 4 1.3 versicolor #> 5 6.5 2.8 4.6 1.5 versicolor #> 6 5.7 2.8 4.5 1.3 versicolor #> # ... with 44 more rows #> #> [[3]] #> # A tibble: 50 x 5 #> Sepal.Length Sepal.Width Petal.Length Petal.Width Species #> <dbl> <dbl> <dbl> <dbl> <fct> #> 1 6.3 3.3 6 2.5 virginica #> 2 5.8 2.7 5.1 1.9 virginica #> 3 7.1 3 5.9 2.1 virginica #> 4 6.3 2.9 5.6 1.8 virginica #> 5 6.5 3 5.8 2.2 virginica #> 6 7.6 3 6.6 2.1 virginica #> # ... with 44 more rows group_keys(ir) #> # A tibble: 3 x 1 #> Species #> <fct> #> 1 setosa #> 2 versicolor #> 3 virginica • group_map() group_map，group_modify,group_walk等三个函数是purrr类具有迭代风格的函数。简单关系数据的数据清洗一般不涉及，常用在建模等方面。 但是目前函数是实验性的，未来可能会发生变化。 # return a list # 返回列表 mtcars %>% group_by(cyl) %>% group_map(~ head(.x, 2L)) #> [[1]] #> # A tibble: 2 x 10 #> mpg disp hp drat wt qsec vs am gear carb #> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 22.8 108 93 3.85 2.32 18.6 1 1 4 1 #> 2 24.4 147. 62 3.69 3.19 20 1 0 4 2 #> #> [[2]] #> # A tibble: 2 x 10 #> mpg disp hp drat wt qsec vs am gear carb #> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 21 160 110 3.9 2.62 16.5 0 1 4 4 #> 2 21 160 110 3.9 2.88 17.0 0 1 4 4 #> #> [[3]] #> # A tibble: 2 x 10 #> mpg disp hp drat wt qsec vs am gear carb #> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <int> <int> <int> <int> #> 1 18.7 360 175 3.15 3.44 17.0 0 0 3 2 #> 2 14.3 360 245 3.21 3.57 15.8 0 0 3 4 iris %>% group_by(Species) %>% group_modify(~ { .x %>% purrr::map_dfc(fivenum) %>% mutate(nms = c("min", "Q1", "median", "Q3", "max")) }) #> # A tibble: 15 x 6 #> # Groups: Species [3] #> Species Sepal.Length Sepal.Width Petal.Length Petal.Width nms #> <fct> <dbl> <dbl> <dbl> <dbl> <chr> #> 1 setosa 4.3 2.3 1 0.1 min #> 2 setosa 4.8 3.2 1.4 0.2 Q1 #> 3 setosa 5 3.4 1.5 0.2 median #> 4 setosa 5.2 3.7 1.6 0.3 Q3 #> 5 setosa 5.8 4.4 1.9 0.6 max #> 6 versicolor 4.9 2 3 1 min #> # ... with 9 more rows 分组后批量输出 # group_walk dir.create(temp <- tempfile()) iris %>% group_by(Species) %>% group_walk(~ write.csv(.x, file = file.path(temp, paste0(.y$Species, ".csv"))))
list.files(temp, pattern = "csv\$")
• group_cols()

gdf <- iris %>% group_by(Species)
gdf %>% select(group_cols())
#> # A tibble: 150 x 1
#> # Groups:   Species [3]
#>   Species
#>   <fct>
#> 1 setosa
#> 2 setosa
#> 3 setosa
#> 4 setosa
#> 5 setosa
#> 6 setosa
#> # ... with 144 more rows

### 2.3.8 其它函数

• between
between(1:12, 7, 9)
#>  [1] FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE
• pull
mtcars %>% pull(-1)
#>  [1] 4 4 1 1 2 1 4 2 2 4 4 3 3 3 4 4 4 1 2 1 1 2 2 4 2 1 2 2 4 6 8 2
mtcars %>% pull(cyl)
#>  [1] 6 6 4 6 8 6 8 4 4 6 6 8 8 8 8 8 8 4 4 4 4 8 8 8 8 4 4 4 8 6 8 4
• distinct
df <- tibble(
x = sample(10, 100, rep = TRUE),
y = sample(10, 100, rep = TRUE)
)

distinct(df, x)
distinct(df, x, .keep_all = TRUE)
distinct(df, diff = abs(x - y))

lag(x, n = 1L, default = NA, order_by = NULL, ...)

lead(x, n = 1L, default = NA, order_by = NULL, ...)
lag(1:5)
#> [1] NA  1  2  3  4
#> [1]  2  3  4  5 NA

lag(1:5, n = 1)
#> [1] NA  1  2  3  4
lag(1:5, n = 2)
#> [1] NA NA  1  2  3

order_by 参数控制顺序。

# If data are not already ordered, use order_by
scrambled <- slice_sample(tibble(year = 2000:2005, value = (0:5) ^ 2), prop = 1)

wrong <- mutate(scrambled, previous_year_value = lag(value))
arrange(wrong, year)
#> # A tibble: 6 x 3
#>    year value previous_year_value
#>   <int> <dbl>               <dbl>
#> 1  2000     0                   1
#> 2  2001     1                  25
#> 3  2002     4                  NA
#> 4  2003     9                   4
#> 5  2004    16                   0
#> 6  2005    25                   9

right <- mutate(scrambled, previous_year_value = lag(value, order_by = year))
arrange(right, year)
#> # A tibble: 6 x 3
#>    year value previous_year_value
#>   <int> <dbl>               <dbl>
#> 1  2000     0                  NA
#> 2  2001     1                   0
#> 3  2002     4                   1
#> 4  2003     9                   4
#> 5  2004    16                   9
#> 6  2005    25                  16

• cummean cumsum cumall cumany

x <- c(1, 3, 5, 2, 2)
cummean(x)
#> [1] 1.00 2.00 3.00 2.75 2.60
cumsum(x) / seq_along(x)
#> [1] 1.00 2.00 3.00 2.75 2.60

cumall(x < 5)
#> [1]  TRUE  TRUE FALSE FALSE FALSE
cumany(x == 3)
#> [1] FALSE  TRUE  TRUE  TRUE  TRUE
• coalesce

x <- sample(c(1:5, NA, NA, NA))
coalesce(x, 0L)
#> [1] 3 2 0 5 4 0 1 0
y <- c(1, 2, NA, NA, 5)
z <- c(NA, NA, 3, 4, 5)
coalesce(y, z)
#> [1] 1 2 3 4 5

df <- tibble( a= sample(c(1:3,NA,NA),10,replace = TRUE))
df %>%
mutate(a = coalesce(a,0))
#> # A tibble: 10 x 1
#>       a
#>   <dbl>
#> 1     1
#> 2     0
#> 3     3
#> 4     2
#> 5     2
#> 6     0
#> # ... with 4 more rows