R学习:R for Data Science(四)
前面我们学了该书得第一章节,使用ggplot2进行数据可视化,现在我们开始学习第二章节,本章节内容丰富,值得收藏!
R学习:R for Data Science(一)
第2章 工作流:基础
既然说到基础,前期学习R基础得过程中整理了最基本的R知识代码,注释清晰,初学者需要反复练习。可以分享给大家,获取方式见文末(本文有点长)
现在我们已经拥有了运行R代码的一些经验,在进一步学习之前,必须先确保具有运行 R 代码的坚实基础,并且掌握RStudio 中一些最有用的功能。
2.1 代码基础
我们可以将 R 当作计算器来使用
1 / 200 * 30
#> [1] 0.15
(59 + 73 + 2) / 3
#> [1] 44.7
sin(pi / 2)
#> [1] 1
可以使用 <- 来创建新对象
x <- 3 * 4
创建对象的所有 R 语句(即赋值语句)都有同样的形式
object_name <- value
输入 <- 太痛苦了,但不要偷懒使用 =,虽然 = 确实也可以赋值,但之后会引起混淆。你可以使用 RStudio 快捷键:Alt+-(Alt 加上减号)
2.2 对象名称
对象名称必须以字母开头,并且只能包含字母、数字、 _ 和 .。如果想让对象名称具有描述性,那么就应该在使用多个单词时遵循某种命名惯例。推荐使用 snake_case 命名法,也就是使用小写单词
i_use_snake_case
otherPeopleUseCamelCase
some.people.use.periods
And_aFew.People_RENOUNCEconvention
你可以通过输入对象名称来查看这个对象
x
#> [1] 12
再进行赋值
this_is_a_really_long_name <- 2.5
要想查看这个变量,可以使用 RStudio 的自动完成功能:输入“this”,按 Tab 键,继续输入字符直到完全匹配这个变量,然后按回车键
再进行一次赋值
r_rocks <- 2 ^ 3
查看一下这个对象
r_rock
#> Error: object 'r_rock' not found
R_rocks
#> Error: object 'R_rocks' not found
R 和用户之间有一个隐含约定:R 可以替用户执行那些单调乏味的计算,但前提是用户必须输入完全精确的指令。不能有输入错误,还要区分大小写。
2.3 函数调用
R 中有大量内置函数,调用方式如下:
function_name(arg1 = val1, arg2 = val2, ...)
我们尝试使用 seq() 函数,它可以生成规则的数值序列,在学习这个函数的同时,我们还可以学习 RStudio 的更多有用功能。输入 se,并按 Tab 键。这时会弹出所有可能的自动完成命令。继续输入(“q”)以消除歧义,或者使用↑和↓箭头键来选择,以选定 seq() 函数。注意弹出的浮动提示信息,它可以告诉你这个函数的参数和作用。如果想要获得更多帮助,按 F1 键就可以在右下角窗格的帮助标签页中看到详细的帮助信息。
选定需要的函数后再按一次 Tab 键。RStudio 会为你自动添加开括号(()和闭括号())。输入参数 1, 10,然后按回车键
seq(1, 10)
#> [1] 1 2 3 4 5 6 7 8 9 10
输入以下代码,你会发现 RStudio 也会自动完成一对双引号以方便输入:
x <- "hello world"
引号和括号必须一直成对出现。RStudio 会尽力帮助我们,但还是有出错并导致不匹配的可能。如果出现不匹配, R 会显示一个 + 号:
> x <- "hello
+
+ 号表明 R 在等待继续输入;它认为你还没有完成输入。这通常意味着你漏掉了一个 " 或者 )。你可以添加漏掉的部分,也可以按 Esc 键中止命令来重新输入。
如果进行了一次赋值, R 不会显示出赋值结果。你最好立刻检查一下
y <- seq(1, 10, length.out = 5)
y
#> [1] 1.00 3.25 5.50 7.75 10.00
这种常用的操作可以简化一下,用括号将赋值语句括起来就可以了,这样相当于连续执行赋值语句和“输出到屏幕”的操作
(y <- seq(1, 10, length.out = 5))
#> [1] 1.00 3.25 5.50 7.75 10.00
第二章内容很少,我们继续学习第三章
第3章 使用dplyr进行数据转换
3.1.1 准备工作
本章将重点讨论如何使用tidyverse中的另一个核心R包dplyr包。我们使用nycflights13 包中的数据来说明 dplyr 包的核心理念,并使用 ggplot2 来帮助我们理解数据。
install.packages('nycflights13')
library(nycflights13)
library(tidyverse)
加载 tidyverse 时,仔细查看输出的冲突信息,它会告诉你 dplyr 覆盖了基础 R 包中的哪些函数。如果想要在加载 dplyr 后使用这些函数的基础版本,那么你应该使用它们的完整名称:stats::filter() 和 stats::lag()。
3.1.2 nycflights13
为了介绍 dplyr 中的基本数据操作,我们需要使用 nycflights13::flights。这个数据框包含了 2013 年从纽约市出发的所有 336 776 次航班的信息。该数据来自于美国交通统计局,可以使用 ?flights 查看其说明文档
a=flights
a
你会发现,列名下面有一行 3 个或 4 个字母的缩写。它们描述了每个变量的类型
· int 表示整数型变量。
· dbl 表示双精度浮点数型变量,或称实数。
· chr 表示字符向量,或称字符串。
· dttm 表示日期时间(日期 + 时间)型变量。
· lgl 表示逻辑型变量,是一个仅包括 TRUE 和 FALSE 的向量。
· fctr 表示因子, R 用其来表示具有固定数目的值的分类变量。
· date 表示日期型变量
3.1.3 dplyr基础
我们将在本章中学习 5 个 dplyr 核心函数,它们可以帮助你解决数据处理中的绝大多数难题。
· 按值筛选观测(filter())。
· 对行进行重新排序(arrange())。
· 按名称选取变量(select())。
· 使用现有变量的函数创建新变量(mutate())。
· 将多个值总结为一个摘要统计量(summarize())。
这些函数都可以和 group_by() 函数联合起来使用, group_by() 函数可以改变以上每个函数的作用范围,让其从在整个数据集上操作变为在每个分组上分别操作。这 6 个函数构成了数据处理语言的基本操作。
前面 5 个函数的工作方式都是相同的。
(1) 第一个参数是一个数据框。
(2) 随后的参数使用变量名称(不带引号)描述了在数据框上进行的操作。
(3) 输出结果是一个新数据框。
利用以上这些属性可以很轻松地将多个简单步骤链接起来,从而得到非常复杂的结果。接下来我们将深入了解,看看如何使用这些操作。
3.2 使用filter()筛选行
filter() 函数可以基于观测的值筛选出一个观测子集。第一个参数是数据框名称,第二个参数以及随后的参数是用来筛选数据框的表达式。例如,我们可以使用以下代码筛选出 1月 1 日的所有航班:
filter(flights, month == 1, day == 1)
#> # A tibble: 842 × 19
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 1 1 517 515 2
#> 2 2013 1 1 533 529 4
#> 3 2013 1 1 542 540 2
#> 4 2013 1 1 544 545 -1
#> 5 2013 1 1 554 600 -6
#> 6 2013 1 1 554 558 -4
#> # ... with 836 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>, 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>
如果运行这行代码, dplyr 就会执行筛选操作,并返回一个新数据框。dplyr 函数从来不修改输入,因此,如果想要保存函数结果,那么你就需要使用赋值操作符 <-
jan1 <- filter(flights, month == 1, day == 1)
R 要么输出结果,要么将结果保存在一个变量中。如果想同时完成这两种操作,那么你可以用括号将赋值语句括起来:
(dec25 <- filter(flights, month == 12, day == 25))
#> # A tibble: 719 × 19
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 12 25 456 500 -4
#> 2 2013 12 25 524 515 9
#> 3 2013 12 25 542 540 2
#> 4 2013 12 25 546 550 -4
#> 5 2013 12 25 556 600 -4
#> 6 2013 12 25 557 600 -3
#> # ... with 713 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>, 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>
3.2.1 比较运算符
为了有效地进行筛选,你必须知道如何使用比较运算符来选择观测。R 提供了一套标准的比较运算符:>、 >=、 <、 <=、 !=(不等于)和 ==(等于)。
当开始使用 R 时,最容易犯的错误就是使用 = 而不是 == 来测试是否相等。当出现这种情况时,你会收到一条有启发性的错误消息
filter(flights, month = 1)
#> Error: filter() takes unnamed arguments. Do you need `==`?
在使用 == 进行比较时,你可能还会遇到另一个常见问题:浮点数。下面的结果可能会令你目瞪口呆
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
3.2.2 逻辑运算符
filter() 中的多个参数是由“与”组合起来的:每个表达式都必须为真才能让一行观测包含在输出中。如果要实现其他类型的组合,你需要使用布尔运算符:& 表示“与”、 | 表示 “或”、 ! 表示“非”。下图给出了布尔运算的完整集合。
以下代码可以找出 11 月或 12 月出发的所有航班:
filter(flights, month == 11 | month == 12)
表达式中的运算顺序和语言中不一样,你不能写成filter(flights,month== 11 |12) 这种形式。这种形式的文字翻译确实是“找出 11 月或 12 月出发的所有航班”,但在代码中则不是这个意思,代码中的含义是找出所有出发月份为 11 | 12 的航班。11 | 12 这个逻辑表达式的值为 TRUE,在数字语境中(如本例), TRUE 就是 1,所以这段代码找出的不是 11 月或 12 月出发的航班,而是 1 月出发的所有航班。
这种问题有一个有用的简写形式:x %in% y。这会选取出 x 是 y 中的一个值时的所有行。我们可以使用这种形式重写上面的代码:
nov_dec <- filter(flights, month %in% c(11, 12))
有时你可以使用德摩根定律将复杂的筛选条件进行简化:!(x & y) 等价于 !x | !y、 !(x |y) 等价于 !x & !y。例如,如果想要找出延误时间(到达或出发)不多于 2 小时的航班,那么使用以下两种筛选方式均可
filter(flights, !(arr_delay > 120 | dep_delay > 120))
filter(flights, arr_delay <= 120, dep_delay <= 120)
3.2.3 缺失值
R 的一个重要特征使得比较运算更加复杂,这个特征就是缺失值,或称 NA(not available,不可用)。NA 表示未知的值,因此缺失值是“可传染的”。如果运算中包含了未知值,那么运算结果一般来说也是个未知值
NA > 5
#> [1] NA
10 == NA
#> [1] NA
NA + 10
#> [1] NA
NA / 2
#> [1] NA
最令人费解的是以下这个结果
NA == NA
#> [1] NA
要想理解为什么会这样,最容易的方式是加入一点背景知识:
# 令x为Mary的年龄。我们不知道她有多大。
x <- NA
# 令y为John的年龄。我们不知道他有多大。
y <- NA
# John和Mary的年龄是相同的吗?
x == y
#> [1] NA
# 我们不知道!
如果想要确定一个值是否为缺失值,可以使用 is.na() 函数:
is.na(x)
#> [1] TRUE
filter() 只能筛选出条件为 TRUE 的行;它会排除那些条件为 FALSE 和 NA 的行。如果想保留缺失值,可以明确指出
df <- tibble(x = c(1, NA, 3))
filter(df, x > 1)
#> # A tibble: 1 × 1
#> x
#> <dbl>
#> 1 3
filter(df, is.na(x) | x > 1)
#> # A tibble: 2 × 1
#> x
#> <dbl>
#> 1 NA
#> 2 3
3.3 使用arrange()排列行
arrange() 函数的工作方式与 filter() 函数非常相似,但前者不是选择行,而是改变行的顺序。它接受一个数据框和一组作为排序依据的列名(或者更复杂的表达式)作为参数。如果列名不只一个,那么就使用后面的列在前面排序的基础上继续排序:
arrange(flights, year, month, day)
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 1 1 517 515 2
#> 2 2013 1 1 533 529 4
#> 3 2013 1 1 542 540 2
#> 4 2013 1 1 544 545 -1
#> 5 2013 1 1 554 600 -6
#> 6 2013 1 1 554 558 -4
#> # ... with 3.368e+05 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>, 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(arr_delay))
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 1 9 641 900 1301
#> 2 2013 6 15 1432 1935 1137
#> 3 2013 1 10 1121 1635 1126
#> 4 2013 9 20 1139 1845 1014
#> 5 2013 7 22 845 1600 1005
#> 6 2013 4 10 1100 1900 960
#> # ... with 3.368e+05 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>, 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>,
缺失值总是排在最后
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
3.4 使用select()选择列
如今,数据集有几百甚至几千个变量已经司空见惯。这种情况下,如何找出真正感兴趣的那些变量经常是我们面临的第一个挑战。通过基于变量名的操作, select() 函数可以让你快速生成一个有用的变量子集。
select() 函数对于航班数据不是特别有用,因为其中只有 19 个变量,但你还是可以通过这个数据集了解一下 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
#> # ... with 3.368e+05 more rows
选择“year”和“day”之间的所有列(包括“year”和“day”)
select(flights, year: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
#> # ... with 3.368e+05 more rows
选择不在“year”和“day”之间的所有列(不包括“year”和“day”)
select(flights, -(year:day))
#> # A tibble: 336,776 × 16
#> dep_time sched_dep_time dep_delay arr_time sched_arr_time
#> <int> <int> <dbl> <int> <int>
#> 1 517 515 2 830 819
#> 2 533 529 4 850 830
#> 3 542 540 2 923 850
#> 4 544 545 -1 1004 1022
#> 5 554 600 -6 812 837
#> 6 554 558 -4 740 728
#> # ... with 3.368e+05 more rows, and 12 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>
还可以在 select () 函数中使用一些辅助函数
· startswith("abc"):匹配以“abc”开头的名称。 · endswith("xyz"):匹配以“xyz”结尾的名称。 · contains("ijk"):匹配包含“ijk”的名称。 · matches("(.)\1"):选择匹配正则表达式的那些变量。这个正则表达式会匹配名称中有 重复字符的变量。我们将在后面学习到更多关于正则表达式的知识。 · num_range("x", 1:3):匹配 x1、 x2 和 x3。
select() 可以重命名变量,但我们很少这样使用它,因为这样会丢掉所有未明确提及的变量。我们应该使用 select() 函数的变体 rename() 函数来重命名变量,以保留所有未明确提及的变量
rename(flights, tail_num = tailnum)
#> # A tibble: 336,776 × 19
#> year month day dep_time sched_dep_time dep_delay
#> <int> <int> <int> <int> <int> <dbl>
#> 1 2013 1 1 517 515 2
#> 2 2013 1 1 533 529 4
#> 3 2013 1 1 542 540 2
#> 4 2013 1 1 544 545 -1
#> 5 2013 1 1 554 600 -6
#> 6 2013 1 1 554 558 -4
#> # ... with 3.368e+05 more rows, and 13 more variables:
#> # arr_time <int>, sched_arr_time <int>, 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 × 19
#> time_hour air_time year month day dep_time
#> <dttm> <dbl> <int> <int> <int> <int>
#> 1 2013-01-01 05:00:00 227 2013 1 1 517
#> 2 2013-01-01 05:00:00 227 2013 1 1 533
#> 3 2013-01-01 05:00:00 160 2013 1 1 542
#> 4 2013-01-01 05:00:00 183 2013 1 1 544
#> 5 2013-01-01 06:00:00 116 2013 1 1 554
#> 6 2013-01-01 05:00:00 150 2013 1 1 554
#> # ... with 3.368e+05 more rows, and 13 more variables:
#> # sched_dep_time <int>, 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>
3.5 使用mutate()添加新变量
除了选择现有的列,我们还经常需要添加新列,新列是现有列的函数。这就是 mutate() 函数的作用
mutate() 总是将新列添加在数据集的最后,因此我们需要先创建一个更狭窄的数据集,以便能够看到新变量。记住,当使用 RStudio 时,查看所有列的最简单的方法就是使用 View()函数
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 × 9
#> year month day dep_delay arr_delay distance air_time
#> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 2013 1 1 2 11 1400 227
#> 2 2013 1 1 4 20 1416 227
#> 3 2013 1 1 2 33 1089 160
#> 4 2013 1 1 -1 -18 1576 183
#> 5 2013 1 1 -6 -25 762 116
#> 6 2013 1 1 -4 12 719 150
#> # ... with 3.368e+05 more rows, and 2 more variables:
#> # gain <dbl>, speed <dbl>
一旦创建,新列就可以立即使用
mutate(flights_sml,
gain = arr_delay - dep_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
#> <int> <int> <int> <dbl> <dbl> <dbl> <dbl>
#> 1 2013 1 1 2 11 1400 227
#> 2 2013 1 1 4 20 1416 227
#> 3 2013 1 1 2 33 1089 160
#> 4 2013 1 1 -1 -18 1576 183
#> 5 2013 1 1 -6 -25 762 116
#> 6 2013 1 1 -4 12 719 150
#> # ... with 3.368e+05 more rows, and 3 more variables:
#> # gain <dbl>, hours <dbl>, gain_per_hour <dbl>
如果只想保留新变量,可以使用 transmute() 函数
transmute(flights,
gain = arr_delay - dep_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.62
#> 4 -17 3.05 -5.57
#> 5 -19 1.93 -9.83
#> 6 16 2.50 6.40
#> # ... with 3.368e+05 more rows
3.5.1 常用创建函数
创建新变量的多种函数可供你同 mutate() 一同使用。最重要的一点是,这种函数必须是向量化的:它必须接受一个向量作为输入,并返回一个向量作为输出,而且输入向量与输出向量具有同样数目的分量。
算术运算符: +、 -、 *、 /、 ^
它们都是向量化的,使用所谓的“循环法则”。如果一个参数比另一个参数短,那么前者会自动扩展到同样的长度。
算术运算符的另一用途是与我们后面将很快学到的聚集函数结合起来使用。例如, 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 × 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
对数函数: log()、 log2() 和 log10()
在处理取值范围横跨多个数量级的数据时,对数是特别有用的一种转换方式。它还可以将乘法转换成加法,其他条件相同的情况下,我推荐使用 log2() 函数,因为很容易对其进行解释:对数标度的数值增加 1 个单位,意味着初始数值加倍;减少 1 个单位,则意味着初始数值减半。
偏移函数
lead() 和 lag() 函数可以返回一个序列的领先值和滞后值。它们可以计算出序列的移动差值(如 x – lag(x))或发现序列何时发生了变化(x != lag(x))
(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()、commin() 和 cummax(); dplyr 还提供了 cummean() 函数以计算累加均值。
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
好吧,今天先到这。
另外,最近收集了一些很好的资源,分享给大家,顺便能涨一些粉,主要有
1. R语言学习基础知识代码
2. 19年中标的各门类国自然题目汇总,以及17年的国自然汇总,部分含摘要!
3. R语言学习书籍
R语言实战(中文完整版)
R数据科学(中文完整版)
ggplot2:数据分析与图形艺术
30分钟学会ggplot2
4. TCGA数据整理
前期从https://xenabrowser.net/datapages/ (UCSC Xena)数据库下载的TCGA数据,传到了百度云上备份。
ggplot2速查表pdf(可复制)
感兴趣的话,转发朋友圈或者100人以上的微信群,截图发到公众号,即可获取全部资源的百度云链接,希望大家赶紧下载。你们的支持是我前进的动力,感谢。