2.3 常用函数
本小节介绍dplyr处理数据时常用的函数,类似sql中的case_when、count、distinct、row_number、between等函数。
2.3.1 条件判断
dplyr::if_else()
相比于base::ifelse
,if_else
输出类型更为严格,无论TRUE
或FALSE
输出类型一致,这样计算速度更快。
dplyr::if_else()
参数:
if_else(condition, true, false, missing = NULL)
<- sample(1:10,5)
x if_else(x>5,"大于五","小于等于五",missing = "空值")
#> [1] "大于五" "大于五" "大于五" "大于五" "小于等于五"
与ifelse
不同的是,if_else
保留类型
<- factor(sample(letters[1:5], 10, replace = TRUE))
x 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
当条件嵌套较多时,使用case_when
,使代码可读并且不易出错。与sql 中的case when 等价。
<- 1:50
x case_when(
%% 35 == 0 ~ "fizz buzz",
x %% 5 == 0 ~ "fizz",
x %% 7 == 0 ~ "buzz",
x 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"
<- as.Date(c('2018-10-01', '2018-10-02', '2018-10-03','2018-10-04'))
Dates case_when(
== '2018-10-01' ~ Dates - 1,
Dates == '2018-10-02' ~ Dates + 1,
Dates == '2018-10-03' ~ Dates + 2,
Dates TRUE ~ Dates
)#> [1] "2018-09-30" "2018-10-03" "2018-10-05" "2018-10-04"
结合 mutate 动词使用
%>%
starwars mutate(性别 = case_when(
== "male" ~ "雄性",
sex == "female" ~ "雌性",
sex == "hermaphroditic" ~ "雌雄同体",
sex TRUE ~ "无"
%>%
)) pull(性别) %>%
table()
#> .
#> 雌性 雌雄同体 无 雄性
#> 16 1 10 60
pull()功能与 data$.类似,为了在管道中使用设计
2.3.3 计数函数
- 计数
count()
函数用来计数。下面两种表达方式等价。
%>% count(a, b)
df # same above
%>% group_by(a, b) %>% summarise(n = n()) df
%>% count(species)
starwars #> # 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 等价
%>% group_by(species) %>% summarise(n = n())
starwars #> # 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))
等价,但是更快更简洁。当我们需要给门店或订单之类数据去重计算时采用该函数。
<- sample(1:10, 1e5, rep = TRUE)
x 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]
<- c(5, 1, 3, 2, 2, NA)
x 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))
<- 1:10
x <- 10:1
y 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()
# 筛选第一行
%>% slice(1L)
mtcars #> # 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
# 筛选最后一行
%>% slice(n())
mtcars #> # 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至最后一行
%>% slice(5:n())
mtcars #> # 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
# 基于现有顺序筛选前面行或最后行
%>% slice_head(n = 5)
mtcars #> # 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
%>% slice_tail(n = 5)
mtcars #> # 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
# 基于变量筛选
%>% slice_min(mpg, n = 5) #最小的五行
mtcars #> # 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
%>% slice_max(mpg, n = 5) #最大的五行
mtcars #> # 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参数控制
%>% slice_min(cyl, n = 1)
mtcars #> # 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
%>% slice_min(cyl, n = 1, with_ties = FALSE)
mtcars #> # 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 参数控制是否可以重复。
%>% slice_sample(n = 5)
mtcars #> # 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
%>% slice_sample(n = 5, replace = TRUE)
mtcars #> # 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 参数调整抽样权重
# 重量大的会更容易抽到
%>% slice_sample(weight_by = wt, n = 5)
mtcars #> # 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
- 分组操作
<- tibble(
df group = rep(c("a", "b", "c"), c(1, 2, 4)),
x = runif(7)
)%>% group_by(group) %>% slice_head(n = 2)
df #> # 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参数时的差异
%>% group_by(group) %>% slice_head(prop = 0.4) #仅c组返回一个,因为c组3个数字的 40%的前面还有数
df #> # A tibble: 1 x 2
#> # Groups: group [1]
#> group x
#> <chr> <dbl>
#> 1 c 0.344
%>% group_by(group) %>% slice_head(prop = 0.5) # 因为a组只有一个数字,前50%位没有数字
df #> # 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()不会改变数据框
<- mtcars %>% group_by(cyl)
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:
%>% summarise(
by_cyl 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操作
%>% group_by(vsam = vs + am) %>%
mtcars group_vars()
#> [1] "vsam"
- group_split()
目前该函数是实验性的,group_split() 功能与 base::split()相似,按照数据集的分组变量切割数据集。如下,将 iris 数据集按照 Species 分组并切割成长度为3的列表,每个子元素是 Species 变量的子数据集。Species 变量包含setosa
、versicolor
、virginica
三种情况。
<- iris %>%
ir 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 ::map_dfc(fivenum) %>%
purrrmutate(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$")
unlink(temp, recursive = TRUE)
- group_cols()
选择分组变量
<- iris %>% group_by(Species)
gdf %>% select(group_cols())
gdf #> # 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 其它函数
有针对性学习函数可以有效提高学习效率,先浏览一遍 dplyr 中函数,再挑选觉得对自己有用的函数学习即可。
- between
between(1:12, 7, 9)
#> [1] FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE
- pull
%>% pull(-1)
mtcars #> [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
%>% pull(cyl)
mtcars #> [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
<- tibble(
df 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))
- lead lag
在向量中查找“向前”或滞后的值,在比较当前值以及前后值时比较有用。
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
lead(1:5)
#> [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`
<- slice_sample(tibble(year = 2000:2005, value = (0:5) ^ 2), prop = 1)
scrambled
<- mutate(scrambled, previous_year_value = lag(value))
wrong 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
<- mutate(scrambled, previous_year_value = lag(value, order_by = year))
right 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
该函数在我们计算下单间隔天数时比较简洁方便
如需了解更多,可以通过学习slider
包知道更多“滑动窗口函数”。
- cummean cumsum cumall cumany
累计系列函数
<- c(1, 3, 5, 2, 2)
x 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
用一组向量值替换NAS,该函数受 SQL 的 COALESCE 函数启发。
<- sample(c(1:5, NA, NA, NA))
x coalesce(x, 0L)
#> [1] 3 2 0 5 4 0 1 0
<- c(1, 2, NA, NA, 5)
y <- c(NA, NA, 3, 4, 5)
z coalesce(y, z)
#> [1] 1 2 3 4 5
在数据框中替换NA
<- tibble( a= sample(c(1:3,NA,NA),10,replace = TRUE))
df %>%
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