本文主要是介绍【学习笔记】R数据科学(R for Data Science)—第3章 使用dplyr进行数据转换,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
dplyr包是tidyverse中的一个核心R包。
dplyr的5个核心函数:
- 按值筛选观测(filter())
- 对行进行重新排序(arrange())
- 按名称选取变量(select())
- 使用现有变量的函数创建新变量(mutate())
- 将多个值总结为一个摘要统计量(summarize())
nycflights13 :: flights这个数据框包含了2013年从纽约市出发的所有336776次航班的信息。
View(flights) 可以在RStudio查看器中看到整个flights数据集。
比较运算符
比较运算符:>, >=, <, <=, !=(不等于)和 ==(等于)
逻辑运算符
①布尔运算符:&表示“与”,| 表示“或”,! 表示“非”。
② x %in% y:会选取出x是y中的一个值时的所有行。
③使用德摩根定律:!(x & y)等价于!x | !y、!(x | y)等价于!x & !y。
缺失值
缺失值NA,not available。
如果运算中包含了NA,那么运算结果一般来说也是NA。
is.na()函数可以判断一个值是否为NA。
na.rm():除去缺失值
filter()函数只能筛选出条件为TRUE的行,它会排除那些条件为FALSE和NA的行。
arrange()
改变行的顺序,接受一个数据框和一组作为排序依据的列名(或者更复杂的表达式)作为参数。如果列名不止一个,就使用后面的列在前面排序的基础上继续排序。
desc()
按列进行降序排序
select()
快速生成一个有用的变量子集。
可以在select()函数中使用一些辅助函数:
- starts_with(“abc”):匹配以abc开头的名称
- ends_with(“xyz”):匹配以xyz结尾的名称
- contains(“ijk”):匹配包含ijk的名称
- matches("(.)\1"):选择匹配正则表达式的变量
- num_range(“x”, 1:3):匹配x1,x2和x3
用rename()函数来重命名变量能保留所有未明确提及的变量。
mutate()
将新列添加在数据集的最后。
一旦创建,新列就可以立即使用。
算数运算符
+, -, *, /, ^
模运算符
%/%(整除触发), %%(求余)
对数函数
log(), log2(), log10()
偏移函数
lead()和lag()函数可以返回一个序列的领先值和滞后值。他们可以计算出序列的移动差值或发现序列何时发生了变化。
累加和滚动聚合
累加和、累加积、累加最小数、累加最大值、累加均值:cumsum(), cumprod(), cummin(), cummax(), cummean()。
逻辑比较
<, <=, >, >=, !=
排秩
min_rank():可以完成最常用的排秩任务。默认的排秩方式是,最小的值获得最前面的名次,使用desc(x)可以让最大的值获得最前面的名次。
min_rank()的变体:row_number(), dense_rank(), percent_rank(), cume_dist(), ntile()。
分组
summarize()
- 可以将数据框折叠成一行。
- 需要和group_by()配合使用。group_by()将分析单位从整个数据集更改为单个分组。在分组后的数据框上使用dplyr函数时,它们会自动地应用到每个分组。
ungroup():取消分组。
group_by()和summarize()的组合构成了使用dplyr包时最常用的操作之一:分组摘要。
虽然与summarize()函数结合起来使用是最有效的,但分组也可以与mutate()和filter()函数结合,以完成非常便捷的操作。
管道(%>%)
管道可以显著提高代码的可读性
x %>% f(y)会转换为f(x,y);x %>% f(y) %>% g(z)会转换为g(f(x,y),z),以此类推。
计数
n(x):不需要任何参数,并返回当前分组的大小
sum(!is_na(x)):计算出非缺失值的数量
n_distinct(x):计算出唯一值的数量
count():如not_cancelled %>% count(dest)
逻辑值的计数和比例:sum(x > 10), mean(y == 0)。当与数值型函数一同使用时,TRUE会转换为1,FALSE会转换为0。这使得sum()和mean()非常适用于逻辑值,sum(x)可以找出x中TRUE的数量,mean(x)可以找出比例。
摘要函数
位置度量:mean(x)(均值), median(x)(中位数)
分散程度度量:sd(x)(均方误差), IQR(x)(四分位距),mad(x)(绝对中位差)。(四分位距和绝对中位差基本等价,更适合有离群点的情况)
秩的度量:min(x), quantile(x,0.25)(分位数,是中位数的扩展,例如quantile(x,0.25)会找出x中按从小到大顺序大于前25%而小于后75%的值), max(x)
定位度量:first(x), nth(x,2), last(x)
练习题
3.2.4
(1)找出满足以下条件的所有航班。
a.到达时间延误2小时或更多的航班。
library(nycflights13)
filter(flights, arr_delay >= 120)
b.飞往休斯顿(IAH机场或HOU机场)的航班。
filter(flights, dest == "IAH" | dest == "HOU")filter(flights, dest %in% c("IAH", "HOU"))
c.由联合航空(United)、美利坚航空(American)或三角洲航空(Delta)运营的航班。
filter(flights, carrier == "UA" | carrier == "AA" | carrier == "DL")filter(flights, carrier %in% c("UA", "AA", "DL"))
d.夏季(7、8、9月)出发的航班。
filter(flights, month == 7 | month == 8 | month == 9)filter(flights, month %in% c(7, 8, 9))filter(flights, month %in% c(7:9)) # filter(flights, month %in% 7:9)
e.到达时间延误超过2小时,但出发时间没有延误的航班。
filter(flights, arr_delay >= 120 & dep_delay <= 0)
f.延误至少1小时,但飞行过程弥补回30分钟的航班。
filter(flights, dep_delay >= 60 & arr_delay == dep_delay - 30)
g.出发时间在午夜和早上6点之间(包括0点和6点)的航班。
filter(flights, dep_time >= 000 & dep_time <= 600)
(2)dplyr中对筛选有帮助的另一个函数是between()。它的作用是什么?你能使用这个函数来简化解决前面问题的代码吗?
# d
filter(flights, between(month, 7, 9))# g
filter(flights, between(dep_time, 000, 600))
(3)dep_time有缺失值的航班有多少?其他变量的缺失值情况如何?这样的行表示什么情况?
result <- filter(flights, is.na(dep_time))
nrow(result)
head(result)
到达时间也是NA,有可能是这些航班被取消了。
(4)为什么NA ^ 0的值不是NA?为什么NA | TRUE的值不是NA?为什么FALSE & NA的值不是NA?
所有数字的0次方是1,“或”有真为真,“和”有假为假。
3.3
(1)如何使用arrange()将缺失值排在最前面?
df <- tibble(x = c(5, 2, NA))
df
arrange(df, desc(is.na(x)))
head(arrange(flights, desc(is.na(dep_delay)), dep_delay))
(2)对flights排序以找出延误时间最长的航班。找出出发时间最早的航班。
# 找出延误时间最长的航班
head(arrange(flights, desc(dep_delay)),1)# 找出出发时间最早的航班
head(arrange(flights, dep_delay), 1)
(3)对flights排序以找出速度最快的航班。
head(arrange(flights, desc(distance / air_time), 1))
(4)哪个航班的飞行时间最长?哪个最短?
3.4
(1)从flights数据集中选择dep_time、dep_delay、arr_time和arr_delay,通过头脑风暴找出尽可能多的方法。
select(flights, dep_time, dep_delay, arr_time, arr_delay)
select(flights, c("dep_time", "dep_delay", "arr_time", "arr_delay"))
select(flights, any_of(c("dep_time", "dep_delay", "arr_time", "arr_delay")))
(2)如果在select()函数中多次计入一个变量名,那么会发生什么情况?
select(flights, dep_time, dep_time, dep_time)
(3)one_of()函数的作用是什么?为什么它结合以下向量使用时非常有用?
vars <- c("year", "month", "day", "dep_delay", "arr_delay")
vars <- c("year", "month", "day", "dep_delay", "arr_delay")
vars
select(flights, one_of(vars))
(4)以下代码的运行结果是否出乎意料?选择辅助函数处理大小写的默认方式是什么?如何改变默认方式?
select(flights, contains("TIME"))
选择辅助函数处理大小写的默认方式是TRUE。
select(flights, contains("TIME", ignore.case = FALSE))
3.5.2
(1)虽然现在的dep_time和sched_dep_time变量方便阅读,但不适合计算,因为它们实际上并不是连续型数值。将它们转换成一种更方便的表示形式,即从午夜开始的分钟数。
flights_ <- mutate(flights, dep_time_min = (dep_time %/% 100 * 60 + dep_time %% 100) %% 1440,sched_dep_time_min = (sched_dep_time %/% 100 * 60 + sched_dep_time %% 100) %% 1440)# 为避免代码冗余,构建一个函数:
time2min <- function(x){(x %/% 100 * 60 + x %% 100) %% 1440
}flight_new <- mutate(flights,dep_time_min = time2min(dep_time),sched_dep_time_min = time2min(sched_dep_time))
这题不明白,在http://www.360doc.com/content/20/1109/23/71039787_945054327.shtml看的答案。
(2)比较air_time和arr_time - dep_time。你期望看到什么?实际又看到了什么?如何解决这个问题?
a <- mutate(flights, air = (arr_time - dep_time))
a
select(a, air)
期望看到air_time 和 arr_time - dep_time的值相同,实际上air_time小于arr_time - dep_time,原因是air_time不包括飞机在地面的滑行时间,仅仅指从起飞到进入着陆之间的时间。
(3)比较dep_time, sched_dep_time和dep_delay。你期望这3个数值之间具有何种关系?
期望:dep_time - sched_dep_time = dep_delay
(4)使用排秩函数找出10个延误时间最长的航班。如何处理名次相同的情况?仔细阅读min_rank()的帮助文件。
head(arrange(mutate(flights, delay_rank = min_rank(dep_delay)), desc(delay_rank)), 10)
(5)1:3 + 1:10会返回什么?为什么?
(6)R提供了哪些三角函数?
3.6.7
(1)通过头脑风暴,至少找出5种方法来确定一组航班的典型延误特征。思考以下场景:
- 一架航班50%的时间会提前15分钟,50%的时间会延误15分钟。
- 一架航班总是会延误10分钟。
- 一架航班50%的时间会提前30分钟,50%的时间会延误30分钟。
- 一架航班99%的时间会准时,1%的时间会延误2个小时。
哪一种更重要?到达延误还是出发延误?
到达延误更重要。
(2)找出另外一种方法,这种方法要可以给出与not_cancelled %>% count(dest)和not_cancelled %>% count(tailnum, wt = distance)同样的输出(不能使用count())。
# Method 1
not_cancelled %>%count(dest)# Method 2
not_cancelled %>%group_by(dest) %>%summarize(n = length(dest))# Method 3
not_cancelled %>%group_by(dest) %>%summarize(n = n())
# Method 1
not_cancelled %>%count(tailnum, wt = distance)# Method 2
not_cancelled %>%group_by(tailnum) %>%summarize(n = sum(distance))
(3)我们对已取消航班的定义(is.na(dep_delay)) | (is.na(arr_delay))稍有欠佳。为什么?哪一列才是最重要的?
影响arr_delay的因素有很多,有可能是飞机没有起飞,也可能是飞机遇到突发情况在其他机场降落。
(4)查看每天取消的航班数量。其中存在模式吗?已取消航班的比例与平均延误时间有关系吗?
这题答案来源→https://cloud.tencent.com/developer/article/1810872
(5)哪个航空公司的延误情况最严重?挑战:你能否分清这个是由于糟糕的机场设备,还是航空公司的问题?为什么能?为什么不能?(提示:考虑一下flights %>% group_by(carrier, dest)%>% summarize(n())。)
这题答案来源于→https://cloud.tencent.com/developer/article/1810872
(6)计算每架飞机在第一次延误超过1小时前的飞行次数。
(7)count()函数中的sort参数的作用是什么?何时应该使用这个参数?
3.7
(1)查看常用的新变量函数和筛选函数的列表。当它们与分组操作结合使用时,功能有哪些变化?
(2)哪一架飞机(用机尾编号来识别,tailnum)具有最差的准点记录?
(3)如果想要尽量避免航班延误,那么应该在一天中的那个时间搭乘飞机?
(4)计算每个目的地的延误总时间的分钟数,以及每架航班到每个目的地的延误时间比例。
(5)延误通常是由临时原因造成的:即使最初引起延误的问题已经解决,但因为要让前面的航班先起飞,所以后面的航班也会延误。使用lag()函数探究一架航班延误与前一架航班延误之间的关系。
(6)查看每个目的地。你能否发现有些航班的速度快得可疑?(也就是说,这些航班的数据可能是错误的。)计算出目的地的最短航线的飞行时间。哪架航班在空中的延误时间最长?
(7)找出至少有两个航空公司的所有目的地。使用数据集中的信息对航空公司进行排名。
这篇关于【学习笔记】R数据科学(R for Data Science)—第3章 使用dplyr进行数据转换的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!