5.3 行排列arrange()
Arrange()
的工作原理与filter()
类似,不同之处在于它不是对行进行过滤,而是改变它们的顺序。它需要一个数据帧和一组列名(或更复杂的表达式)来排序。如果你的列名不止一个,那么其它的列将依序进行排序:
arrange(flights, year, month, day)
#> # A tibble: 336,776 x 19
#> year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
#> <int> <int> <int> <int> <int> <dbl> <int> <int>
#> 1 2013 1 1 517 515 2 830 819
#> 2 2013 1 1 533 529 4 850 830
#> 3 2013 1 1 542 540 2 923 850
#> 4 2013 1 1 544 545 -1 1004 1022
#> 5 2013 1 1 554 600 -6 812 837
#> 6 2013 1 1 554 558 -4 740 728
#> # … with 336,770 more rows, and 11 more variables: arr_delay <dbl>,
#> # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#> # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
desc()
按降序对列重新排序:
arrange(flights, desc(dep_delay))
#> # A tibble: 336,776 x 19
#> year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
#> <int> <int> <int> <int> <int> <dbl> <int> <int>
#> 1 2013 1 9 641 900 1301 1242 1530
#> 2 2013 6 15 1432 1935 1137 1607 2120
#> 3 2013 1 10 1121 1635 1126 1239 1810
#> 4 2013 9 20 1139 1845 1014 1457 2210
#> 5 2013 7 22 845 1600 1005 1044 1815
#> 6 2013 4 10 1100 1900 960 1342 2211
#> # … with 336,770 more rows, and 11 more variables: arr_delay <dbl>,
#> # carrier <chr>, flight <int>, tailnum <chr>, origin <chr>, dest <chr>,
#> # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
如果排序中出现缺失值(NA
),则缺失值排在最后:
df <- tibble(x = c(5, 2, NA))
arrange(df, x)
#> # A tibble: 3 x 1
#> x
#> <dbl>
#> 1 2
#> 2 5
#> 3 NA
arrange(df, desc(x))
#> # A tibble: 3 x 1
#> x
#> <dbl>
#> 1 5
#> 2 2
#> 3 NA
5.4 列选择select()
如果想从数百甚至数千个变量的数据集中选择出感兴趣的变量,Select()
允许使用基于变量名称选择有用的子集。
例如我们想从航班数据通过Select()
挑选出感兴趣的变量:
# Select columns by name
select(flights, year, month, day)
#> # A tibble: 336,776 x 3
#> year month day
#> <int> <int> <int>
#> 1 2013 1 1
#> 2 2013 1 1
#> 3 2013 1 1
#> 4 2013 1 1
#> 5 2013 1 1
#> 6 2013 1 1
#> # … with 336,770 more rows
# Select all columns between year and day (inclusive)
select(flights, year:day)
#> # A tibble: 336,776 x 3
#> year month day
#> <int> <int> <int>
#> 1 2013 1 1
#> 2 2013 1 1
#> 3 2013 1 1
#> 4 2013 1 1
#> 5 2013 1 1
#> 6 2013 1 1
#> # … with 336,770 more rows
# Select all columns except those from year to day (inclusive)
select(flights, -(year:day))
#> # A tibble: 336,776 x 16
#> dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier
#> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 517 515 2 830 819 11 UA
#> 2 533 529 4 850 830 20 UA
#> 3 542 540 2 923 850 33 AA
#> 4 544 545 -1 1004 1022 -18 B6
#> 5 554 600 -6 812 837 -25 DL
#> 6 554 558 -4 740 728 12 UA
#> # … with 336,770 more rows, and 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>
在使用select()
是还有许多辅助函数:
-
starts_with("abc")
: 匹配以“abc”开头的名字。 -
ends_with("xyz")
: 匹配以“xyz”结尾的名字。 -
contains("ijk")
: 匹配包含“ijk”的名称。 -
matches("(.)\\1")
: 选择匹配正则表达式的变量。这个匹配任何包含重复字符的变量。 -
num_range("x", 1:3)
: 匹配x1
,x2
和x3
。
select()
可以对变量重命名,但很少有用,因为它会删除所有未选择的变量。可以通过 rename()
代替使用,它会保留所有select()
未选择的变量:
rename(flights, tail_num = tailnum)
#> # A tibble: 336,776 x 19
#> year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
#> <int> <int> <int> <int> <int> <dbl> <int> <int>
#> 1 2013 1 1 517 515 2 830 819
#> 2 2013 1 1 533 529 4 850 830
#> 3 2013 1 1 542 540 2 923 850
#> 4 2013 1 1 544 545 -1 1004 1022
#> 5 2013 1 1 554 600 -6 812 837
#> 6 2013 1 1 554 558 -4 740 728
#> # … with 336,770 more rows, and 11 more variables: arr_delay <dbl>,
#> # carrier <chr>, flight <int>, tail_num <chr>, origin <chr>, dest <chr>,
#> # air_time <dbl>, distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>
另一种选择是select()
与everything()
辅助函数一起使用。如果您有一些变量想要移动到数据框的开头,可通过如下操作完成。
select(flights, time_hour, air_time, everything())
#> # A tibble: 336,776 x 19
#> time_hour air_time year month day dep_time sched_dep_time
#> <dttm> <dbl> <int> <int> <int> <int> <int>
#> 1 2013-01-01 05:00:00 227 2013 1 1 517 515
#> 2 2013-01-01 05:00:00 227 2013 1 1 533 529
#> 3 2013-01-01 05:00:00 160 2013 1 1 542 540
#> 4 2013-01-01 05:00:00 183 2013 1 1 544 545
#> 5 2013-01-01 06:00:00 116 2013 1 1 554 600
#> 6 2013-01-01 05:00:00 150 2013 1 1 554 558
#> # … with 336,770 more rows, and 12 more variables: dep_delay <dbl>,
#> # arr_time <int>, sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
#> # flight <int>, tailnum <chr>, origin <chr>, dest <chr>, distance <dbl>,
#> # hour <dbl>, minute <dbl>
5.5 添加新变量mutate()
除了选择现有列之外,可通过mutate()
添加新列。
mutate()
总是在数据集的末尾添加新列,在 RStudio 中时,查看所有列的最简单方法是View().
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 336,770 more rows
请注意,您可以引用您刚刚创建的列:
mutate(flights_sml,
gain = dep_delay - arr_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
#> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 2013 1 1 2 11 1400 227 -9 3.78
#> 2 2013 1 1 4 20 1416 227 -16 3.78
#> 3 2013 1 1 2 33 1089 160 -31 2.67
#> 4 2013 1 1 -1 -18 1576 183 17 3.05
#> 5 2013 1 1 -6 -25 762 116 19 1.93
#> 6 2013 1 1 -4 12 719 150 -16 2.5
#> # … with 336,770 more rows, and 1 more variable: gain_per_hour <dbl>
如果您只想保留新变量,请使用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 336,770 more rows
5.5.1 创建函数
可以使用mutate()
创建新变量的函数有很多。key的属性是函数必须是向量化的:它必须以一个向量的值作为输入,返回一个与输出值相同数量的向量。下面列出了一些常用的函数.
- 算术操作符:
+
,-
,*
,/
,^
。这些都是矢量化的,使用所谓的“回收规则”。如果其中一个参数比另一个短,它将自动扩展为相同的长度。当其中一个参数是单个数字时,可以这样表示:air_time / 60
,hours* 60 +minute
,等。
算术运算符在与函数结合使用时也很有用。例如,x / sum(x)
计算总数的比例,y - mean(y)
计算与平均值的差值。
-
模运算:
%/%
(整数除法)和%%
(余数),其中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 336,770 more rows
-
日志:
log()
,log2()
,log10()
。对于处理多个数量级的数据,对数是一种非常有用的转换。它们还可以将乘法关系转换为加法关系,这是我们在建模过程中会提到的一个特性。
在其他条件相同的情况下,我推荐使用log2()
,因为它很容易解释:对数尺度上的差异为1
对应于原始尺度的倍增,而-1
对应于减半。 -
offset:
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()
开始。它提供最常见的排序类型(如1、2、2、4)。默认值给出最小值的等级;使用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
```
网友评论