21 天从入门到精通 R 语言|使用 R 语言进行数据处理(一)
为了让大家更好的理解本文的内容,欢迎各位培训班会员参加明天晚上 9 点的直播课:「使用 R 语言进行数据处理(一)」
该课程是「R 语言数据科学的第 4 课时」,课程主页(点击文末的阅读原文即可跳转):
https://rstata.duanshu.com/#/brief/course/229b770183e44fbbb64133df929818ec
本次课程将细致的讲解使用 R 语言处理数据的各种操作。
使用 R 语言作为计算器
1 / 200 * 30
#> [1] 0.15
(59 + 73 + 2) / 3
#> [1] 44.66667
sin(pi / 2)
#> [1] 1
但是上面的结果都是直接被打印了出来,不能再次调用,因此我们需要将他们保存起来,最快速的方式就是保存为对象,因此我们要首先了解 R 语言中对象的命名规则:
实际上没有规则,只要你能记得每次使用对象的时候都用 ` 把它括起来,那你几乎可以使用任意形式的对象名称,甚至:
`1` <- 1
`a b` <- 2
`1` + `a b`
#> [1] 3
不过尽管如此,建议你遵循下列规则:
不能包含空格; 不能包含运算符,例如 -
,+
,*
,/
;不能包含 .
,?
;不能以数字开头; 大小写敏感; 建议不要使用中文变量名,变量名不宜使用 a, b, c 这种缺乏实际含义的字符,可以使用简单的英文或英文缩写。例如 pop 之类的。
数据操作:dplyr 包的使用
在下面的案例中我们将使用 flights 数据集演示:
nycflights13::flights -> flights
flights
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 2013 1 1 517 515 2 830 819 11 UA
#> 2 2013 1 1 533 529 4 850 830 20 UA
#> 3 2013 1 1 542 540 2 923 850 33 AA
#> 4 2013 1 1 544 545 -1 1004 1022 -18 B6
#> 5 2013 1 1 554 600 -6 812 837 -25 DL
#> 6 2013 1 1 554 558 -4 740 728 12 UA
#> 7 2013 1 1 555 600 -5 913 854 19 B6
#> 8 2013 1 1 557 600 -3 709 723 -14 EV
#> 9 2013 1 1 557 600 -3 838 846 -8 B6
#> 10 2013 1 1 558 600 -2 753 745 8 AA
#> # … with 336,766 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> # ¹sched_dep_time, ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
filter 函数
由于包导入顺序的问题,在我电脑上,stats 包的 filter 函数覆盖了 dplyr 包的 filter 函数,所以在下面的操作中我将使用 dplyr::filter 表示使用 dplyr 包的 filter 函数:
library(tidyverse)
dplyr::filter
#> function (.data, ..., .by = NULL, .preserve = FALSE)
#> {
#> check_by_typo(...)
#> by <- enquo(.by)
#> if (!quo_is_null(by) && !is_false(.preserve)) {
#> abort("Can't supply both `.by` and `.preserve`.")
#> }
#> UseMethod("filter")
#> }
#> <bytecode: 0x7fee4dea13d8>
#> <environment: namespace:dplyr>
顾名思义,filter 函数的功能是用于行筛选,例如我们选择出所有 1 月 1 日的航班:
dplyr::filter(flights, month == 1, day == 1)
#> # A tibble: 842 × 19
#> year month day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 2013 1 1 517 515 2 830 819 11 UA
#> 2 2013 1 1 533 529 4 850 830 20 UA
#> 3 2013 1 1 542 540 2 923 850 33 AA
#> 4 2013 1 1 544 545 -1 1004 1022 -18 B6
#> 5 2013 1 1 554 600 -6 812 837 -25 DL
#> 6 2013 1 1 554 558 -4 740 728 12 UA
#> 7 2013 1 1 555 600 -5 913 854 19 B6
#> 8 2013 1 1 557 600 -3 709 723 -14 EV
#> 9 2013 1 1 557 600 -3 838 846 -8 B6
#> 10 2013 1 1 558 600 -2 753 745 8 AA
#> # … with 832 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> # ¹sched_dep_time, ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
更多的时候我会使用管道操作符,下面的操作和上面的操作功能一样:
flights %>%
dplyr::filter(month == 1, day == 1)
#> # A tibble: 842 × 19
#> year month day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 2013 1 1 517 515 2 830 819 11 UA
#> 2 2013 1 1 533 529 4 850 830 20 UA
#> 3 2013 1 1 542 540 2 923 850 33 AA
#> 4 2013 1 1 544 545 -1 1004 1022 -18 B6
#> 5 2013 1 1 554 600 -6 812 837 -25 DL
#> 6 2013 1 1 554 558 -4 740 728 12 UA
#> 7 2013 1 1 555 600 -5 913 854 19 B6
#> 8 2013 1 1 557 600 -3 709 723 -14 EV
#> 9 2013 1 1 557 600 -3 838 846 -8 B6
#> 10 2013 1 1 558 600 -2 753 745 8 AA
#> # … with 832 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> # ¹sched_dep_time, ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
但是这样只会把筛选结果打印出来,如果你在后面的代码中使用这个结果,你需要把它保存起来:
flights %>%
dplyr::filter(month == 1, day == 1) -> jan1
思考:dplyr::filter 函数使用逻辑表达式(与或非)进行筛选,尝试进行更多的筛选。
flights %>%
dplyr::filter(month == 1 | day == 1)
flights %>%
dplyr::filter(month == 1 & day == 1)
flights %>%
dplyr::filter(month != 1, day != 1)
flights %>%
dplyr::filter(month >= 1, day != 1)
flights %>%
dplyr::filter(month == 11 | month == 12)
flights %>%
dplyr::filter(month %in% c(11, 12))
flights %>%
dplyr::filter(!month %in% 1:10)
需要注意的是 ==
, >=
, >
等运算符号进行的是精确筛选,由于精度的问题,可能会产生下列错误:
sqrt(2) ^ 2 == 2
#> [1] FALSE
1 / 49 * 49 == 1
#> [1] FALSE
这个时候我们可以使用 near 函数进行模糊比较:
near(sqrt(2) ^ 2, 2)
#> [1] TRUE
near(1 / 49 * 49, 1)
#> [1] TRUE
说到逻辑表达式,R 语言里面有一类非常值得关注的函数 is.*
,例如 is.na
:
tibble(
x = c(1, NA, 2),
y = c(2, 1, NA)
) -> df
df %>%
dplyr::filter(is.na(x))
#> # A tibble: 1 × 2
#> x y
#> <dbl> <dbl>
#> 1 NA 1
df %>%
dplyr::filter(!is.na(x))
#> # A tibble: 2 × 2
#> x y
#> <dbl> <dbl>
#> 1 1 2
#> 2 2 NA
df %>%
dplyr::filter(across(everything(), ~!is.na(.x)))
#> # A tibble: 1 × 2
#> x y
#> <dbl> <dbl>
#> 1 1 2
# 等价于
df %>%
dplyr::filter(if_all(everything(), ~!is.na(.x)))
#> # A tibble: 1 × 2
#> x y
#> <dbl> <dbl>
#> 1 1 2
需要注意,缺失值不能使用 ==
运算:
x <- NA
y <- NA
x == y
#> [1] NA
identical(x, y)
#> [1] TRUE
x == NA
#> [1] NA
is.na(x)
#> [1] TRUE
补充学习:
dplyr::filter 还有三个衍生函数,非常好用:filter_all, filter_at 和 filter_if,不过这三个函数已经废弃了(未来不会再有新功能了),现在更建议组合使用 filter 和 across/if_all/if_any 函数:
例如我们筛选出 mtcars 数据集中所有变量都大于 150 的观测值:
as_tibble(mtcars) -> mtcars
filter_all(mtcars, all_vars(. > 150))
#> # A tibble: 0 × 11
#> # … with 11 variables: mpg <dbl>, cyl <dbl>, disp <dbl>, hp <dbl>, drat <dbl>,
#> # wt <dbl>, qsec <dbl>, vs <dbl>, am <dbl>, gear <dbl>, carb <dbl>
# 等价于:
dplyr::filter(mtcars, across(everything(), ~ .x > 150))
# 等价于
dplyr::filter(mtcars, if_all(everything(), ~ .x > 150))
结果没有一个观测值满足条件,那我们再筛选出某个变量大于 150 的观测值:
filter_all(mtcars, any_vars(. > 150))
#> # A tibble: 21 × 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 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 21.4 6 258 110 3.08 3.22 19.4 1 0 3 1
#> 4 18.7 8 360 175 3.15 3.44 17.0 0 0 3 2
#> 5 18.1 6 225 105 2.76 3.46 20.2 1 0 3 1
#> 6 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 7 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
#> 8 17.8 6 168. 123 3.92 3.44 18.9 1 0 4 4
#> 9 16.4 8 276. 180 3.07 4.07 17.4 0 0 3 3
#> 10 17.3 8 276. 180 3.07 3.73 17.6 0 0 3 3
#> # … with 11 more rows
# 等价于
rowAny <- function(x) rowSums(x) > 0
dplyr::filter(mtcars, rowAny(across(where(is.numeric), ~ .x > 150)))
# 等价于
dplyr::filter(mtcars, if_any(where(is.numeric), ~ .x > 150))
如果我们想筛选出所有以 d 开头的变量,且这些变量中的某个变量的值为偶数,我们就需要用 filter_at 函数了:
filter_at(mtcars, vars(starts_with("d")),
any_vars((. %% 2) == 0))
#> # A tibble: 13 × 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 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 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 7 10.4 8 472 205 2.93 5.25 18.0 0 0 3 4
#> 8 10.4 8 460 215 3 5.42 17.8 0 0 3 4
#> 9 14.7 8 440 230 3.23 5.34 17.4 0 0 3 4
#> 10 15.5 8 318 150 2.76 3.52 16.9 0 0 3 2
#> 11 15.2 8 304 150 3.15 3.44 17.3 0 0 3 2
#> 12 13.3 8 350 245 3.73 3.84 15.4 0 0 3 4
#> 13 19.2 8 400 175 3.08 3.84 17.0 0 0 3 2
# 等价于
dplyr::filter(mtcars, rowAny(across(c(starts_with("d")), ~ .x %% 2 == 0)))
# 等价于
dplyr::filter(mtcars, if_any(starts_with("d"), ~ .x %% 2 == 0))
filter_if 函数则可对符合某一条件的变量进行筛选,例如筛选所有数值型变量不等于0的观测值:
filter_if(mtcars, ~is.numeric(.), all_vars(. != 0))
#> # A tibble: 7 × 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 22.8 4 108 93 3.85 2.32 18.6 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 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
#> 5 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1
#> 6 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2
#> 7 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2
# 等价于
dplyr::filter(mtcars, across(where(is.numeric), ~ .x != 0))
# 等价于
dplyr::filter(mtcars, if_all(where(is.numeric), ~ .x != 0))
帮助文档中还给出了一个例子,大家看看是什么意思:
filter_if(mtcars, ~ all(floor(.) == .), all_vars(. != 0))
#> # A tibble: 7 × 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 22.8 4 108 93 3.85 2.32 18.6 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 33.9 4 71.1 65 4.22 1.84 19.9 1 1 4 1
#> 5 27.3 4 79 66 4.08 1.94 18.9 1 1 4 1
#> 6 30.4 4 95.1 113 3.77 1.51 16.9 1 1 5 2
#> 7 21.4 4 121 109 4.11 2.78 18.6 1 1 4 2
# 等价于
is_int <- function(x) all(floor(x) == x)
dplyr::filter(mtcars, across(where(is_int), ~ .x != 0))
# 等价于
dplyr::filter(mtcars, if_all(where(is_int), ~ .x != 0))
arrange 函数
arrange 函数可以用于观测值排序,例如:
arrange(flights, year, month, day)
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 2013 1 1 517 515 2 830 819 11 UA
#> 2 2013 1 1 533 529 4 850 830 20 UA
#> 3 2013 1 1 542 540 2 923 850 33 AA
#> 4 2013 1 1 544 545 -1 1004 1022 -18 B6
#> 5 2013 1 1 554 600 -6 812 837 -25 DL
#> 6 2013 1 1 554 558 -4 740 728 12 UA
#> 7 2013 1 1 555 600 -5 913 854 19 B6
#> 8 2013 1 1 557 600 -3 709 723 -14 EV
#> 9 2013 1 1 557 600 -3 838 846 -8 B6
#> 10 2013 1 1 558 600 -2 753 745 8 AA
#> # … with 336,766 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> # ¹sched_dep_time, ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
arrange(flights, desc(dep_delay))
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_de…¹ dep_d…² arr_t…³ sched…⁴ arr_d…⁵ carrier
#> <int> <int> <int> <int> <int> <dbl> <int> <int> <dbl> <chr>
#> 1 2013 1 9 641 900 1301 1242 1530 1272 HA
#> 2 2013 6 15 1432 1935 1137 1607 2120 1127 MQ
#> 3 2013 1 10 1121 1635 1126 1239 1810 1109 MQ
#> 4 2013 9 20 1139 1845 1014 1457 2210 1007 AA
#> 5 2013 7 22 845 1600 1005 1044 1815 989 MQ
#> 6 2013 4 10 1100 1900 960 1342 2211 931 DL
#> 7 2013 3 17 2321 810 911 135 1020 915 DL
#> 8 2013 6 27 959 1900 899 1236 2226 850 DL
#> 9 2013 7 22 2257 759 898 121 1026 895 DL
#> 10 2013 12 5 756 1700 896 1058 2020 878 AA
#> # … with 336,766 more rows, 9 more variables: flight <int>, tailnum <chr>,
#> # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
#> # minute <dbl>, time_hour <dttm>, and abbreviated variable names
#> # ¹sched_dep_time, ²dep_delay, ³arr_time, ⁴sched_arr_time, ⁵arr_delay
排序的时候就要注意缺失值的位置了:
df <- tibble(x = c(5, 2, NA))
arrange(df, x)
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 2
#> 2 5
#> 3 NA
arrange(df, desc(x))
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 5
#> 2 2
#> 3 NA
可以看到,不管怎么样,缺失值总是会被排在最后。那么如果我们想把缺失值排在前面怎么做呢?
arrange(df, desc(is.na(x)), x)
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 NA
#> 2 2
#> 3 5
看起来很懵,实际上它是借助一个新的变量进行排序的:
df %>%
mutate(
newx = desc(is.na(x))
) %>%
arrange(newx, x) %>%
select(-newx)
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 NA
#> 2 2
#> 3 5
select 函数
select 函数可以用于列的选择(变量筛选):
select(flights, year, month, day)
#> # A tibble: 336,776 × 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
#> 7 2013 1 1
#> 8 2013 1 1
#> 9 2013 1 1
#> 10 2013 1 1
#> # … with 336,766 more rows
select(flights, year:day)
select(flights, -(year:day))
select(flights, starts_with("y"))
select(flights, ends_with("r"))
select(flights, contains("ye"))
select(flights, matches("y(.*)r"))
tibble(
x1 = 1:3,
x2 = 2:4,
x3 = 4:6
) %>%
select(num_range("x", 1:2))
#> # A tibble: 3 × 2
#> x1 x2
#> <int> <int>
#> 1 1 2
#> 2 2 3
#> 3 3 4
select 函数还可以用于变量的重命名:
flights %>%
select(y = year)
flights %>%
select(year) %>%
rename(y = year)
select 函数也有三个非常好用的衍生函数:select_all, select_if, select_at,不过同样这些函数都被废弃了,建议使用 select/rename_with/where 函数:
例如选择所有的数值型变量:
select_if(mtcars, is.numeric)
#> # A tibble: 32 × 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 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
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
#> # … with 22 more rows
# 等价于
select(mtcars, where(is.numeric))
例如将所有变量名不包含 "ar" 或 "c" 开头的变量重命名为其大写形式:
mtcars %>%
select_at(vars(!contains("ar"), starts_with("c")), toupper)
#> # A tibble: 32 × 10
#> MPG CYL DISP HP DRAT WT QSEC VS AM CARB
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 6 160 110 3.9 2.62 16.5 0 1 4
#> 2 21 6 160 110 3.9 2.88 17.0 0 1 4
#> 3 22.8 4 108 93 3.85 2.32 18.6 1 1 1
#> 4 21.4 6 258 110 3.08 3.22 19.4 1 0 1
#> 5 18.7 8 360 175 3.15 3.44 17.0 0 0 2
#> 6 18.1 6 225 105 2.76 3.46 20.2 1 0 1
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 4
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 2
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 2
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4
#> # … with 22 more rows
# 等价于
mtcars %>%
select(!contains("ar") | starts_with("c")) %>%
rename_with(toupper)
再例如,将所有的变量重命名为其大写形式:
mtcars %>%
select_all(toupper)
#> # A tibble: 32 × 11
#> MPG CYL DISP HP DRAT WT QSEC VS AM GEAR CARB
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 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
#> 7 14.3 8 360 245 3.21 3.57 15.8 0 0 3 4
#> 8 24.4 4 147. 62 3.69 3.19 20 1 0 4 2
#> 9 22.8 4 141. 95 3.92 3.15 22.9 1 0 4 2
#> 10 19.2 6 168. 123 3.92 3.44 18.3 1 0 4 4
#> # … with 22 more rows
# 等价于
mtcars %>%
rename_with(toupper)
mutate 函数
mutate 函数的功能是对数据框的变量进行修改或者添加新列:
flights %>%
select(year:day, ends_with("delay"),
distance, air_time) -> flights_sml
flights_sml %>%
mutate(gain = dep_delay - arr_delay,
speed = distance / air_time * 60)
#> # A tibble: 336,776 × 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
flights_sml %>%
mutate(gain = dep_delay - arr_delay,
hours = air_time / 60,
gain_per_hour = gain / hours)
#> # A tibble: 336,776 × 10
#> year month day dep_delay arr_delay distance air_time gain hours gain_pe…¹
#> <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, and abbreviated variable name ¹gain_per_hour
如果你只想保留修改或新增的列,可以使用 transmute 函数:
flights %>%
transmute(gain = dep_delay - arr_delay,
hours = air_time / 60,
gain_per_hour = gain / hours)
#> # A tibble: 336,776 × 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 也有 mutate_all, mutate_at 和 mutate_if 三个衍生函数,同样。。。也都被废弃了,更建议使用 across 和 mutate 的组合:
例如计算所有数值型变量的均值:
tibble(x = 1:3, y = 3:5, z = 5:7) -> df
df %>%
mutate_if(is.numeric, mean, na.rm = T)
#> # A tibble: 3 × 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 2 4 6
#> 2 2 4 6
#> 3 2 4 6
# 等价于
df %>%
mutate(across(where(is.numeric), mean, na.rm = TRUE))
计算 x 和以 y 开头的变量的均值:
df %>%
mutate_at(vars(c(x, starts_with("y"))), mean)
#> # A tibble: 3 × 3
#> x y z
#> <dbl> <dbl> <int>
#> 1 2 4 5
#> 2 2 4 6
#> 3 2 4 7
# 等价于
df %>%
mutate(across(c(x, starts_with("y")), mean, na.rm = TRUE))
计算所有变量的均值:
df %>%
mutate_all(mean)
#> # A tibble: 3 × 3
#> x y z
#> <dbl> <dbl> <dbl>
#> 1 2 4 6
#> 2 2 4 6
#> 3 2 4 6
# 等价于
df %>%
mutate(across(everything(), mean))
常用的函数
+
,-
,*
,/
,^
,%/%
(整除),%%
(求余);log()
,log2()
,log10()
;lag()
,lead()
,diff()
;cumsum()
,cumprod()
,cummin()
,cummax()
,cummean()
;==
,>=
,>
,<
,<=
,!=
;排名函数:
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
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
因为时间关系,第一部分就先到这里了~
直播信息
为了让大家更好的理解上面的内容,欢迎各位培训班会员参加明天晚上 9 点的直播课:「使用 R 语言进行数据处理(一)」
直播地址:腾讯会议(需要报名 RStata 培训班参加) 讲义材料:需要报名 RStata 培训班,详情可阅读:一起来学习 R 语言和 Stata 啦!学习过程中遇到的问题也可以随时提问!
更多关于 RStata 会员的更多信息可添加微信号 r_stata 咨询: