今天是生信星球陪你的第123天
你想找辆共享单车,发现满街都是别家车,没有一辆你能骑。
你想学点生信,搜了“初学者教程”,满眼尽是高大上,没有一句能看懂。
终于你跨越茫茫宇宙,来到生信星球,发现了初学者的新大陆!
如果你对R语言一无所知,建议先学习《零基础系列》
本系列的参考资料是:学R必备的神书《R数据科学》,如果你还不了解这本书,👇点这里。
系列连载:
小洁写于2018.9.4 高能预警:全文很长,适合用电脑打开,对照练习。如果用手机看,瞄两眼思维导图,记住常用的几个函数名字就可以洗洗睡了。这应该是我写的史上最长教程TOT
在《小洁详解
install.packages('nycflights13')
library(nycflights13)
library(tidyverse)
使用nycflights13包的flights作为示例数据。
拿到一个数据首先要观察它。-我忘了谁说的,反正好有道理
2013年从纽约市出发的所有336776次航班的信息。
flights #就瞅一眼,看看几行几列
?flights #好好瞅瞅每列表示什么意思
View(flights)#以表格的形式好好瞅瞅
class(flights)#了解他的类别
行列数:336,776 x 19
year,month,day -日期
dep_time sched_dep_time 起飞时间 实际/计划
dep_delay 起飞延误时间
arr_time sched_arr_time 到达时间 实际/计划
arr_delay 到达延误时间
carrier 航空公司缩写
flight 航班号
tailnum 飞机尾号
origin/dest 出发地/目的地
air_time 飞行总时间,单位min
distance 出发地和目的地两机场间的距离,单位英里
hour、minute 计划停歇时间
time_hour补充:变量类型
int -整数
dbl-双精度浮点数、实数
dttm-日期+时间
lgl-逻辑型变量,仅包括TRUE和FALSE
fctr-因子,R中用因子表示具有固定数目的值的分类。
date-日期型变量
filter 按行筛选
arrange 给行排序
select 按列筛选
mutate 根据原有列生成新列
summarize 摘要统计
关于行和列的补充:行=观测,列=变量
注意:dplyr函数不修改原数据框,只从原数据框中生成新数据框,如果新生成的数据框不赋值给一个新的变量,那么就会丢失。
R要么输出结果,要么赋值。将赋值语句用括号括起来则可以同时完成这两种操作。
filter(flights, month == 1, day == 1) #输出结果
jan1 <>1, day == 1) #赋值
(dec25 <>12, day == 25))#两种操作
>,>=,<><=,!= ,="">
双精度浮点数用near(a,b)取代a==b
布尔运算符号 &|!并、或、非
复杂的筛选条件简化 %in%
filter(flights, month == 11 | month == 12)
filter(flights, month %in% c(11, 12))
复杂的筛选条件简化 !
!(x & y)等价于!x | !y,!(x | y)等价于!x & !y
tips:括号要从内向外计算
filter(flights, !(arr_delay > 120 | dep_delay > 120))
filter(flights, arr_delay <>120, dep_delay <>120)
NA,表示有一个值,但是不知道具体是啥,相当于个陌生人。而NULL相当于,根本没人。。。
NA与NULL的区分:一个元素值全为NA的向量,它的长度是存在的,就等于元素的个数。而如果把一个向量的所有元素的值都设为NULL,这个向量就变成了“空值”,其长度为0,表明“空无一物”。(出处:Mountain's_blog)
df <>1, NA, 3))
filter(df, x > 1)
filter(df, is.na(x) | x > 1) #is.na(x)判断是否为缺失值
arrange(flights, year, month, day)
arrange(flights, desc(dep_delay))
无论正序倒序,空值排在最后
df <>5, 2, NA))
arrange(df, x)
arrange(df, desc(x))
如果要将NA排在最前面,则需要使用
arrange(flights, desc(is.na(dep_time)), dep_time)
(2)对比了一下中英文的问题和答案,感觉“出发时间最早”,作者想表达的可能是提前出发时间最长的(比如有一班提前43分钟飞走的,恕我孤陋寡闻不知道有这种操作啊),而不是半夜12点起飞的。有点歧义。
(3)fastest,我以为要距离除以飞行时间这样算。我认为应该是
mutate(flights,vic=distance/air_time) %>%arrange(desc(vic)) %>%select(year,month,day,vic,everything())
结果给出的答案是飞行时间最短的,应该是不严谨,欢迎发表不同意见。
(4)第四题英文原文说的是Which flights traveled the longest? Which traveled the shortest?
中文书籍翻译为飞行时间最长、最短,英文答案则认为是距离最长、最短,这个歧义也是哈哈。没有什么深究的意义,个人偏向于距离,至于真正表达的意思应该只有hadley大神自己清楚了。
小洁续写于2018.9.10
#1. 根据列名单独选择某几列
select(flights, year, month, day)
#2.连选几列
select(flights, year:day)
#3.连选+反选
select(flights, -(year:day))
#4.辅助函数-选择列名符合以下要求的
starts_with('abc'): 以abc开头的
ends_with('xyz'): 以xyz结尾的
contains('ijk'):包含ijk的
matches('(.)\\1'): 匹配正则表达式的
#5.重命名
rename(flights, tail_num = tailnum) #将tailnum修改为tail_name
#6.某几列移动到开头,everything表示其余各列
select(flights, time_hour, air_time, everything())
-------------------------------------------------(我又偷窥答案了)-------------------------------------------------------------
(2)select()函数多次计入一个变量名,会自动去重复,只保留第一次。
(3)one_of()
vars <>'year', 'month', 'day', 'dep_delay', 'arr_delay')
select(flights, one_of(vars))
var是character vector(特征向量),这样写出的select()只不必写多个向量名。
(4)select辅助函数默认忽略大小写,如需修改:
select(flights, contains('TIME', ignore.case = FALSE))
mutate和transmute的区别:mutate生成新列后,添加新列到数据框末尾,生成新数据框。transmute则是只保留新生成的列。这里说的是生成,是指原有列加减乘除等计算出的结果作为新列。
生成新列gain和speed:
flights_sml <>
year:day,
ends_with('delay'),
distance,
air_time
)
mutate(flights_sml,
gain = dep_delay - arr_delay,
speed = distance / air_time * 60
)
新列可以直接参与另一新列的生成,原文“一旦创建,新列就可以立即使用”。这里指的是可以根据新列进行新的计算,再生成新列。
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
)
其实应该是使用group_by和summarize()进行分组摘要。如果没有group_by,就会把整个数据框作为一个整体,会变成一行。
书中的代码中有na.rm = TRUE,删掉的话会变成:
by_day <>
summarise(by_day, delay = mean(dep_delay, na.rm = TRUE))
管道操作会简化代码,数据框名不必重复写多次。
#level一-生成中间产物,不喜欢
by_day <>year, month, day)
summarise(by_day, delay = mean(dep_delay, na.rm = TRUE))
#level二-这个是我习惯的方式
summarise(group_by(flights, year, month, day), delay = mean(dep_delay, na.rm = TRUE))
#level三-管道操作连接两步,数据框名在括号里面
group_by(flights, year, month, day) %>% summarise(delay = mean(dep_delay, na.rm = TRUE))
#level四-管道操作连接两步,数据框名在括号里面
flights %>%group_by( year, month, day) %>% summarise(delay = mean(dep_delay, na.rm = TRUE))
完成数据准备需要分组--摘要统计--筛选。
管道操作连接多行命令时,将管道符号%>%放在上一行末尾。
上面提到,代码中有na.rm = TRUE,删掉的话会变成:
flights %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay))
na.rm = TRUE这个参数会在计算前移除缺失值。
flights %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay, na.rm = TRUE))
移除后计算的方法,还可以用filter筛出非空行列,再行计算。(笨办法)
not_cancelled <- flights %>%
filter(!is.na(dep_delay), !is.na(arr_delay))
not_cancelled %>%
group_by(year, month, day) %>%
summarise(mean = mean(dep_delay))
示例:找出平均延误时间最长的飞机
(根据tailname进行分组,得到的时全年同一架飞机的各种数据)
补充:关于count()和n()的探索:统计每个航空公司各有多少趟航班
carriers <>
s1 <>
s2 <>
mu <>
s3 <>
s4 <>
四种方法统计的结果是一致的,distinct是去重复。
(其实表达的意思是 多级分组)
#先按照年月日分组,也就是按天
daily <>
(per_day <>
#再按照月份汇总摘要
(per_month <>
#再按年汇总,只有一年的数据所以成了一行
(per_year <>
也就是说将分好组的数据框可逆返回到原始数据。
daily %>%
ungroup() %>% # no longer grouped by date
summarise(flights = n()) # all flights
原文“找出每个分组中最差的成员”在例子中,是选择每天延误时间最长的10趟航班
flights_sml %>%
group_by(year, month, day) %>%
filter(rank(desc(arr_delay)) <>10)
找出最受欢迎的目的地,也就是dest中出现次数高的(高于阈值365)。
思路是;分组,计数,筛选
popular_dests <- flights %>%
group_by(dest) %>%
filter(n() > 365)
例:筛选延误的航班,计算各航班的延误时间占目的地总延误时间的比例,并显示指定列。
popular_dests %>%
filter(arr_delay > 0) %>%
mutate(prop_delay = arr_delay / sum(arr_delay)) %>%
select(year:day, dest, arr_delay, prop_delay)
联系客服