除了选择现有的列,我们还经常需要添加新列,新列是现有列的函数。这就是
mutate()
函数的作用
mutate()
总是将新列添加在数据集最后,因此我们需要先创建一个更狭窄的数据集,以便能够看到新变量。
library(dplyr)
library(nycflights13)
flights_sml <- select(flights,year:day,ends_with("delay"),distance,air_time)
mutate(flights_sml,gain=arr_delay-dep_delay,speed=distance/air_time*60)
# A tibble: 336,776 x 9
year month day dep_delay arr_delay distance air_time gain speed
<int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013 1 1 2 11 1400 227 9 370.
2 2013 1 1 4 20 1416 227 16 374.
3 2013 1 1 2 33 1089 160 31 408.
4 2013 1 1 -1 -18 1576 183 -17 517.
5 2013 1 1 -6 -25 762 116 -19 394.
6 2013 1 1 -4 12 719 150 16 288.
7 2013 1 1 -5 19 1065 158 24 404.
8 2013 1 1 -3 -14 229 53 -11 259.
9 2013 1 1 -3 -8 944 140 -5 405.
10 2013 1 1 -2 8 733 138 10 319.
# ... with 336,766 more rows
一旦创建,新列就可以立即使用:
mutate(flights_sml,gain=arr_delay-dep_delay,hours=air_time/60,gain_per_hour=gain/hours)
# A tibble: 336,776 x 10
year month day dep_delay arr_delay distance air_time gain hours gain_per_hour
<int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2013 1 1 2 11 1400 227 9 3.78 2.38
2 2013 1 1 4 20 1416 227 16 3.78 4.23
3 2013 1 1 2 33 1089 160 31 2.67 11.6
4 2013 1 1 -1 -18 1576 183 -17 3.05 -5.57
5 2013 1 1 -6 -25 762 116 -19 1.93 -9.83
6 2013 1 1 -4 12 719 150 16 2.5 6.4
7 2013 1 1 -5 19 1065 158 24 2.63 9.11
8 2013 1 1 -3 -14 229 53 -11 0.883 -12.5
9 2013 1 1 -3 -8 944 140 -5 2.33 -2.14
10 2013 1 1 -2 8 733 138 10 2.3 4.35
# ... with 336,766 more rows
如果只想保留新变量,可以使用transmute()函数:
transmute(flights,gain=arr_delay-dep_delay,hours=air_time/60,gain_per_hour=gain/hours)
# A tibble: 336,776 x 3
gain hours gain_per_hour
<dbl> <dbl> <dbl>
1 9 3.78 2.38
2 16 3.78 4.23
3 31 2.67 11.6
4 -17 3.05 -5.57
5 -19 1.93 -9.83
6 16 2.5 6.4
7 24 2.63 9.11
8 -11 0.883 -12.5
9 -5 2.33 -2.14
10 10 2.3 4.35
# ... with 336,766 more rows
常用创建函数
创建新变量的多种函数可以同mutate
一起使用,但最重要的是这种函数必须是向量化的。
算数运算符 +、-、*、/、^
它们都是向量化的,当参数是单个数值时,这种方式是最有效的:air_time/60
、hours*60+minute
。
模运算符 %/%(整数除法)和%%(求余)
满足x==y*(x%/%y)+(x%%y)
例如在航班数据集种,可以根据dep_time,求出hour和minute
transmute(flights,dep_time,hour=dep_time%/%100,minute=dep_time%%100)
# A tibble: 336,776 x 3
dep_time hour minute
<int> <dbl> <dbl>
1 517 5 17
2 533 5 33
3 542 5 42
4 544 5 44
5 554 5 54
6 554 5 54
7 555 5 55
8 557 5 57
9 557 5 57
10 558 5 58
# ... with 336,766 more rows
对数函数
log()
,log2()
,log10()
在处理取值横跨多个数量级的数据时,对数是一种特别有用的转化方式。它可以将乘法转换成加法,再之后会提到。
偏移函数
lead()
,lag()
(x <- 1:10)
#[1] 1 2 3 4 5 6 7 8 9 10
lag(x)
#[1] NA 1 2 3 4 5 6 7 8 9
lead(x)
#[1] 2 3 4 5 6 7 8 9 10 NA
lead()
,lag()
可以返回序列的领先值或滞后值。
累加和滚动聚合
R提供了计算累加和、累加积、累加最小值、累加最大值的函数:cumsum()
,cumprod()
,cummin()
,cummax()
;dplyr还提供了计算累加均值cummean
。如果想要计算滚动聚合,可以尝试RcppRoll包:
x
#[1] 1 2 3 4 5 6 7 8 9 10
cumsum(x)
#[1] 1 3 6 10 15 21 28 36 45 55
cummean(x)
#[1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5
逻辑比较
<、<=、>、>=
和!=
排秩
排秩函数有很多,可以从min_rank()
函数开始,它完成最常用的排秩任务。默认的方式是,最小的值获得最前面的名次,使用desc(x)
可以让最大值获得最前面的名词。
y <- c(1,2,2,NA,3,4)
min_rank(y)
#[1] 1 2 2 NA 4 5
min_rank(desc(y))
#[1] 5 3 3 NA 2 1
如果min_rank()
无法满足需求,那么可以看一下其变体row_number()
、dense_rank()
、percent_rank()
、cume_dist()
、和ntile()
。
row_number(y)
#[1] 1 2 3 NA 4 5
dense_rank(y)
#[1] 1 2 2 NA 3 4
percent_rank(y)
#[1] 0.00 0.25 0.25 NA 0.75 1.00
cume_dist(y)
#[1] 0.2 0.6 0.6 NA 0.8 1.0
网友评论