dplyr包进行数据转换
使用dplyr进行数据转换
tidyverse 中的另一个核心 R 包 ——dplyr 包。
1 nycflights13包
介绍 dplyr 中的基本数据操作,我们需要使用 nycflights13::flights。这个数据框包含了 2013 年从纽约市出发的所有 336 776 次航班的信息。
install.packages("nycflights13")
library(nycflights13)
library(tidyverse)
想看到整个数据集,可以使用 View(flights),
• int 表示整数型变量。
• dbl 表示双精度浮点数型变量,或称实数。
• chr 表示字符向量,或称字符串。
• dttm 表示日期时间(日期 + 时间)型变量
• lgl 表示逻辑型变量,是一个仅包括 TRUE 和 FALSE 的向量。
• fctr 表示因子,R 用其来表示具有固定数目的值的分类变量。
• date 表示日期型变量。
2 dplyr基础
5 个 dplyr 核心函数:
• 按值筛选观测(filter())。
• 对行进行重新排序(arrange())。
• 按名称选取变量(select())。
• 使用现有变量的函数创建新变量(mutate())。
• 将多个值总结为一个摘要统计量(summarize())。
这些函数都可以和 group_by() 函数联合起来使用,group_by() 函数可以改变以上每个函数的作用范围,让其从在整个数据集上操作变为在每个分组上分别操作。这 6 个函数构成了数据处理语言的基本操作。
2.1 使用filter()筛选行
filter() 函数可以基于观测的值筛选出一个观测子集。第一个参数是数据框名称,第二个参数以及随后的参数是用来筛选数据框的表达式。例如,我们可以使用以下代码筛选出 1月 1 日的所有航班信息:
filter(flights, month == 1, day == 1)
2.1.1 比较运算符
比较运算符:>、>=、<、<=、!=(不等于)和 ==(等于)。
比较浮点数是否相等时,不能使用 ==,而应该使用 near()。
2.1.2 逻辑运算符
布尔运算符:& 表示“与”、| 表示“或”、! 表示“非”。
以下代码可以找出 11 月或 12 月出发的所有航班:
filter(flights, month == 11 | month == 12)
2.2 缺失值
缺失值称 NA(not available,不可用)。NA 表示未知的值,因此缺失值是“可传染的”。如果运算中包含了未知值,那么运算结果一般来说也是个未知值。
filter() 只能筛选出条件为 TRUE 的行;它会排除那些条件为 FALSE 和 NA 的行。如果想保
留缺失值,可以明确指出。
在R中NA代表缺失值,NA是不可用,not avaliable的简称,用来存储缺失信息,这里的NA表示没有,但并不一定是0,NA是不知多少,也可能是0,也可能是任何值,缺失值和值为零完全不同。
关于NA的计算,使用函数na.rm=T/F 可以去掉缺失值。
使用相应的逻辑函数is.na() 可以显示是否存在缺失值NA。
导入需要的包 install.packages("VIM") 。
用ia.na()函数测试数据集sleep中的缺失值。
返回mtcars数据集每一行的缺失值rowSums(mtcars)。
返回mtcars数据集每一列的缺失值cloSums(mtcars)。
使用函数na.omit()去除缺失数据。
使用函数可以去除包含缺失值的行na.omit(mtcars),这样处理会删除很多行,影响数据的完整性。
1 处理缺失值
删除某一个缺失值 na.rm=TRUE。
删除空值所在的整个行 na.omit(数据集名字)。
3 使用arrange()排列行
arrange() 函数的工作方式与 filter() 函数非常相似,但前者不是选择行,而是改变行的
顺序。
arrange(flights, year, month, day)
4 使用select()选择列
select() 函数可以让你快速生成一个有用的变量子集。
# 按名称选择列
select(flights, year, month, day)
# 选择“year”和“day”之间的所有列(包括“year”和“day”)
select(flights, year:day)
# 选择不在“year”和“day”之间的所有列(不包括“year”和“day”)
select(flights, -(year:day))
还可以在 select () 函数中使用一些辅助函数。
• starts_with("abc"):匹配以“abc”开头的名称。
• ends_with("xyz"):匹配以“xyz”结尾的名称。
• contains("ijk"):匹配包含“ijk”的名称。
• matches("(.)\\1"):选择匹配正则表达式的那些变量。这个正则表达式会匹配名称中有
重复字符的变量。
• num_range("x", 1:3):匹配 x1、x2 和 x3。
select() 可以重命名变量,使用 select() 函数的变体 rename() 函数来重命名变量,以保留所有未明确提及的变量:
rename(flights, tail_num = tailnum) #给变量重命名
将 select() 函数和 everything() 辅助函数结合起来使用。当想要将几个变量移到数据框开头时,这种用法非常奏效:
select(flights, time_hour, air_time, everything())
5 使用mutate()添加新变量
mutate() 总是将新列添加在数据集的最后,查看所有列的最简单的方法就是使用 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
)
5.1 常用创建函数
算术运算符:+、-、*、/、^
模运算符:%/% 和 %%
对数函数:log()、log2() 和 log10()
偏移函数:lead() 和 lag() 函数可以返回一个序列的领先值和滞后值。
累加和滚动聚合:R 提供了计算累加和、累加积、累加最小值和累加最大值的函数:cumsum()、cumprod()、commin() 和 cummax();dplyr 还提供了 cummean() 函数以计算累加均值。如果想要计算滚动聚合(即滚动窗口求和),那么可以尝试使用 RcppRoll 包。
逻辑比较:<、<=、>、>= 和 !=
6 使用summarize()进行分组摘要
summarize(),它可以将数据框折叠成一行:
summarize(flights, delay = mean(dep_delay, na.rm = TRUE))
group_by() 可以将分析单位从整个数据集更改为单个分组,在分组后的数据框上使用 dplyr 函数时,它们会自动地应用到每个分组。
按日期分组,可以得到每日平均延误时间:
by_day <- group_by(flights, year, month, day)
summarize(by_day, delay = mean(dep_delay, na.rm = TRUE))
6.1 使用管道组合多种操作
要研究每个目的地的距离和平均延误时间之间的关系,解决这个问题的另一种方法是使用管道,%>%:
delays <- flights %>%
group_by(dest) %>%
summarize(
count = n(), #n() 返回当前分组的大小
dist = mean(distance, na.rm = TRUE),
delay = mean(arr_delay, na.rm = TRUE)
) %>%
filter(count > 20, dest != "HNL")
在阅读代码时,%>% 最好读作“然后”。使用这种方法时,x %>% f(y) 会转换为 f(x, y),x %>% f(y) %>% g(z) 会转换为 g(f(x, y), z),以此类推。支持管道操作是 tidyverse 中的 R 包的核心原则之一。
6.2 缺失值
所有聚合函数都有一个 na.rm 参数,它可以在计算前除去缺失值:
flights %>%
group_by(year, month, day) %>%
summarize(mean = mean(dep_delay, na.rm = TRUE))
也可以通过先去除取消的航班来解决缺失值问题。
not_cancelled <- flights %>%
filter(!is.na(dep_delay), !is.na(arr_delay))
not_cancelled %>%
group_by(year, month, day) %>%
summarize(mean = mean(dep_delay))
6.3 计数
聚合操作中包括一个计数(n())或非缺失值的计数(sum(!is_na()))是个好主意。这样你就可以检查一下,以确保自己没有基于非常少量的数据作出结论。例如,我们查看一下具有最长平均延误时间的飞机(通过机尾编号进行识别):
delays <- not_cancelled %>%
group_by(tailnum) %>%
summarize(
delay = mean(arr_delay)
)
ggplot(data = delays, mapping = aes(x = delay)) +
geom_freqpoly(binwidth = 10)
结果分析:有些飞机的平均延误时间长达 5 小时(300 分钟)。
6.4 常用的摘要函数
位置度量:我们已经使用过 平均mean(x),但中位数median(x) 也非常有用。
not_cancelled %>%
group_by(year, month, day) %>%
summarize(
# 平均延误时间:
avg_delay1 = mean(arr_delay),
# 平均正延误时间:
avg_delay2 = mean(arr_delay[arr_delay > 0])
)
分散程度度量:sd(x)、IQR(x) 和 mad(x)。均方误差(又称标准误差,standard deviation,sd)是分散程度的标准度量方式。四分位距 IQR() 和绝对中位差 mad(x) 基本等价,更适合有离群点的情况。
# 为什么到某些目的地的距离比到其他目的地更多变?
not_cancelled %>%
group_by(dest) %>%
summarize(distance_sd = sd(distance)) %>%
arrange(desc(distance_sd))
秩的度量:min(x)、quantile(x, 0.25) 和 max(x)。分位数是中位数的扩展。例如,quantile(x, 0.25) 会找出 x 中按从小到大顺序大于前25% 而小于后 75% 的值:
# 每天最早和最晚的航班何时出发?
not_cancelled %>%
group_by(year, month, day) %>%
summarize(
first = min(dep_time),
last = max(dep_time)
)
定位度量:first(x)、nth(x, 2) 和 last(x)。这几个函数的作用与 x[1]、x[2] 和 x[length(x)] 相同,只是当定位不存在时(比如尝试从只有两个元素的分组中得到第三个元素),前者允许你设置一个默认值。例如,我们可以找出每天最早和最晚出发的航班:
not_cancelled %>%
group_by(year, month, day) %>%
summarize(
first_dep = first(dep_time),
last_dep = last(dep_time)
)
计数:你已经见过 n(),它不需要任何参数,并返回当前分组的大小。如果想要计算出非
缺失值的数量,可以使用 sum(!is.na(x))。要想计算出唯一值的数量,可以使用 n_distinct(x):
# 哪个目的地具有最多的航空公司?
not_cancelled %>%
group_by(dest) %>%
summarize(carriers = n_distinct(carrier)) %>%
arrange(desc(carriers))
dplyr 提供了一个简单的辅助函数,用于只需要计数的情况:
not_cancelled %>%
count(dest)
可以选择提供一个加权变量。例如,你可以使用以下代码算出每架飞机飞行的总里程
数(实际上就是求和):
not_cancelled %>%
count(tailnum, wt = distance)
逻辑值的计数和比例:sum(x > 10) 和 mean(y == 0)
当与数值型函数一同使用时,TRUE 会转换为 1,FALSE 会转换为 0。这使得 sum() 和mean()非常适用于逻辑值:sum(x) 可以找出 x 中 TRUE 的数量,mean(x) 则可以找出比例。
# 多少架航班是在早上5点前出发的?(这通常表明前一天延误的航班数量)
not_cancelled %>%
group_by(year, month, day) %>%
summarize(n_early = sum(dep_time < 500))
# 延误超过1小时的航班比例是多少?
not_cancelled %>%
group_by(year, month, day) %>%
summarize(hour_perc = mean(arr_delay > 60))
6.5 按多个变量分组
daily <- group_by(flights, year, month, day)
(per_day <- summarize(daily, flights = n())) #每天航班数量
(per_month <- summarize(per_day, flights = sum(flights))) #每月航班数量
(per_year <- summarize(per_month, flights = sum(flights))) #每年航班数量
6.6 取消分组
如果想要取消分组,并回到未分组的数据继续操作,那么可以使用 ungroup() 函数:
daily %>%
ungroup() %>% # 不再按日期分组
summarize(flights = n()) # 所有航班
7 分组新变量(和筛选器)
与 summarize() 函数结合起来使用是最有效的,分组也可以与 mutate() 和 filter()函数结合,以完成非常便捷的操作。
找出每个分组中最差的成员:
flights_sml %>%
group_by(year, month, day) %>%
filter(rank(desc(arr_delay)) < 10)
找出大于某个阈值的所有分组:
popular_dests <- flights %>%
group_by(dest) %>%
filter(n() > 365)
popular_dests
对数据进行标准化以计算分组指标:
popular_dests %>%
filter(arr_delay > 0) %>%
mutate(prop_delay = arr_delay / sum(arr_delay)) %>% #增加了列prop_delay
select(year:day, dest, arr_delay, prop_delay)
本文来自博客园,作者:zhang-X,转载请注明原文链接:https://www.cnblogs.com/YY-zhang/p/15576895.html