https://r4ds.had.co.nz/transform.html#add-new-variables-with-mutate
5.mutate可根据已有的变量添加新的变量
变形函数mutate
除了提取已有列,根据已有的列添加新的列也很常见。mutate()
具有此功能
mutate()
总会添加新的列到已有列的末尾。为了方便查看数据的变化,在Rstudio中可通过View()
实现。
library(nycflights13)
library(tidyverse)
flights_sml <- select(flights,
year:day,
ends_with("delay"),
distance,
air_time
)
mutate(flights_sml,
gain = dep_delay - arr_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.
#> # … with 3.368e+05 more rows
随后,可以使用刚刚添加的列:
mutate(flights_sml,
gain = dep_delay - arr_delay,
hours = air_time / 60,
gain_per_hour = gain / hours
)
如果仅希望保留新添加的变量,通过transmute()
实现:
transmute(flights,
gain = dep_delay - arr_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
#> # … with 3.368e+05 more rows
5.1 创建函数
通过mutate()
添加新变量可以很多功能,而这些创建的函数都必须是矢量化的,即:必须是向量值作为输入,返回相同数目值的一个向量。没有办法列出所有可能使用的函数,但列出了常用的功能:
- 算法操作符:
+
,-
,*
,、
,……
。这些都是使用所谓的“回收规则”进行矢量化的。如果某个参数比其他的要短,这个短的参数会被延伸至相同长度。当参数之一是单个数字时非常有用:air_time / 60
,hours * 60 + minute
等。
算法操作符在使用整合函数时同样有用。例如,x / sum(x)
- 模运算:
%/%
(整数除法)和%%
(余数),其中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
#> # … with 3.368e+05 more rows
- Logs:
log()
,log2()
,log10()
.对数在处理跨越多个数量级的数据时是非常有用的转换。它们还将乘法关系转换为加法,这是建模中回归的一个特征。
在其他条件相同的情况下,建议使用log2(),因为它很容易解释:对数刻度上的1对应于原始刻度上的倍增,-1的差异对应于减半。 - Offsets:
lead()
和lag()
允许引用前导或滞后值。 这允许计算运行差异(例如x - lag(x)
)或查找值何时更改(x!= lag(x)
)。 它们与group_by()
一起使用最为有用。
(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
- 累积和滚动聚合: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()开始。 它执行最常见的排名类型(例如,1st, 2nd, 2nd, 4th)。 默认值为小等级的最小值;使用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
5.5.2 练习
1. Currently dep_time and sched_dep_time are convenient to look at, but hard to compute with because they’re not really continuous numbers. Convert them to a more convenient representation of number of minutes since midnight.
2. Compare air_time with arr_time - dep_time. What do you expect to see? What do you see? What do you need to do to fix it?
3. Compare dep_time, sched_dep_time, and dep_delay. How would you expect those three numbers to be related?
4. Find the 10 most delayed flights using a ranking function. How do you want to handle ties? Carefully read the documentation for min_rank().
5. What does 1:3 + 1:10 return? Why?
6. What trigonometric functions does R provide?