R:数据处理常用包:tidyverse

R4DS:在线电子书用于学习tidyverse的用法

数据科学处理使用tidyverse
data.table
大数据处理首选data.table,多CPU并行运算,100G内存即可支持20亿行的基准测试。速度读取写入速度都比dplyr快。
R和python的数据处理包的速度对比评测
性能评测一般是:group_by和join函数,显然data.table速度快于dplyr.
dplyr data.table
dplyr data.table对比

tidyverse包含多个包

-ggplot2 用于可视化
-dplyr 数据处理
-tidyr 数据处理
-stringr 字符串的处理
-readr 文件的读取
-purrr 函数的迭代
-forcats 处理因子问题
-tibble 实现data.table类似的优雅处理dataframe问题
dplyr参考
数据处理经常用到的包
dplyr,data.table,Base R
测试表明,dplyr的速度要快于data.table.
dplyrtidyverse其中的一个包。
数据处理一般的流程:
1.数据过滤(去重)
2.选择
3.比对,匹配
4.分组
5.排序
6.抽样
在excel中也可以完成上述操作,但是当数量达到十万以上级别后,excel速度慢如蜗牛。

dplyr用法示例

数据去重

distinct(df,V1,V2) 根据V1和V2两个条件来进行去重

新增列

mutate(df,vnew1=v1-v2,vnew2=vnew1+v3) 支持在创建的新列的基础上,再新建列。

过滤函数

filter(df,cond1,cond2,…) 用逗号,隔开表示条件是and的关系
filter(df,cond1|cond2|…) 用竖线|隔开表示条件是or的关系
slice(df,80:100) 选取索引80到100的数据

排序

arrange(df,V1,desc(V2),V3)V1,V3升序,V2降序
arranage(df,V1) 升序排列V1
arrange(df,desc(V3))降序排列V3

选择

select(df,V1,V2,V3)选择V1,V2,V3这三列
select(df,V1:V3) 选择V1到V3列之间的所有列
select(df,-c(v1,V3))选择除V1,V3之外的所有列

分组

group_by(df,V1,V2)df根据V1,V2进行分组

计算统计数据

summarise(df,mean(V1),sum(V4))

随机抽取

sample_n(df,1000)随机抽取1000个数据
sample_frac(df,0.7) 随机抽取70%的数据

参考地址https://www.cnblogs.com/nxld/p/6060533.html

数据格式转换tidyr包

library(tidyr)
library(dplyr)
    1. 缺失值的简单补齐
    1. 长形表变宽形表与宽形表变长形表
        gather-把宽度较大的数据转换成一个更长的形式,它类比于从reshape2包中融合函数的功能
        spread-把长的数据转换成一个更宽的形式,它类比于从reshape2包中铸造函数的功能。
        gather()相反的是spread(),前者将不同的列堆叠起来,后者将同一列分开
长短数据的转换主要是用于ggplot2的出图,ggplot2需要的是长数据,而我们日常输入的数据是宽数据

宽数据实例
下面数据的第一列数字是R中的行号
allinfo内容如下

     province  primary   middle   senior    higher postgraduate
1     北京 109.4579 110.5105 96.20949  98.91572    107.82594
2     天津 113.4776 114.0266 94.79238  99.90067     88.54674
3     河北 114.6299 113.0214 91.19643  87.67520     81.96543
4     山西 107.9786 108.3219 92.03961  82.94410     73.76735
5   内蒙古 109.1339 108.9091 92.13359  89.96668     67.54206
6     辽宁 110.3081 110.8525 91.70425 112.46839     87.90451

allinfoNew内容如下
转换成长数据后
allinfoNew <- allinfo %>% gather(school,value, -province)
将allinfo的所有列,除了province列之外全部合并成两列,一列是school,一列是value.

       province       school     value
1      北京      primary 109.45794
2      天津      primary 113.47760
3      河北      primary 114.62993
4      山西      primary 107.97863
5    内蒙古      primary 109.13391
6      辽宁      primary 110.30810
7      北京       middle 110.51045
8      天津       middle 114.02665
9      河北       middle 113.02139
10     山西       middle 108.32195
11   内蒙古       middle 108.90907
12     辽宁       middle 110.85252
13     北京       senior  96.20949
14     天津       senior  94.79238
15     河北       senior  91.19643
16     山西       senior  92.03961
17   内蒙古       senior  92.13359
18     辽宁       senior  91.70425
19     北京       higher  98.91572
20     天津       higher  99.90067
21     河北       higher  87.67520
22     山西       higher  82.94410
23   内蒙古       higher  89.96668
24     辽宁       higher 112.46839
25     北京 postgraduate 107.82594
26     天津 postgraduate  88.54674
27     河北 postgraduate  81.96543
28     山西 postgraduate  73.76735
29   内蒙古 postgraduate  67.54206
30     辽宁 postgraduate  87.90451

长数据转为宽数据

allinfoFat <- allinfoNew %>% spread(school,value)
allinfoFat和allinfo的内容一致。
school是要拆分的列的对象,value是要拆分列的值。

    1. 列分割与列合并
        separate-将一列按分隔符分割为多列
        unite-将多列按指定分隔符合并为一列

tidyr包:(gather(宽数据转为长数据)、spread(长数据转为宽数据)、unit(多列合并为一列)、separate(将一列分离为多列))

stringr的用法

library(stringr)
x <- c("why", "video", "cross", "extra", "deal", "authority")
str_length(x)#获取字符串的长度
#> [1] 3 5 5 5 4 9
str_c(x, collapse = ", ")#替换分隔符
#> [1] "why, video, cross, extra, deal, authority"
str_sub(x, 1, 2)#提取指定长度的字符串
#> [1] "wh" "vi" "cr" "ex" "de" "au"
str_subset(x, "[aeiou]") #匹配包含aeiou的字符串
#> [1] "video"     "cross"     "extra"     "deal"      "authority"
str_count(x, "[aeiou]")#匹配包含aeiou的字符的数量
#> [1] 0 3 1 2 2 4
str_detect(x, "[aeiou]") #返回是否包含aeiou字符串的逻辑值
#> [1] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE
str_locate(x, "[aeiou]") #返回每个字符串首次匹配的起始位置和终止位置。(例子中需要匹配的字符串长度都是1,所以终止位置和起始位置是一样的)
str_locate_all(x, "[aeiou]") #返回每个字符串所有的与匹配字符匹配的起始位置和终止位置。
str_extract(x, "[aeiou]") #提取每个字符串中与匹配字符串一致的字符
str_match(x, "(.)[aeiou](.)") #匹配
str_replace(x, "[aeiou]", "^") #替换匹配的字符
#[1] "why"       "v^deo"     "cr^ss"     "^xtra"     "d^al"      "^uthority"
str_split(c("a,b", "c,d,e"), ",") #指定使用逗号分割字符串

forcats的 用法

library(forcats)
fct_reorder()#: 按另一个变量重新排序一个因子。
fct_infreq()#:按值的频率对因子重新排序。
fct_relevel()#:手动更改因子的顺序。
fct_lump()#:将一个因素的最少/最频繁值折叠为“其他”。
starwars %>% 
  filter(!is.na(species)) %>%
  count(species, sort = TRUE)
starwars %>%
  filter(!is.na(species)) %>%
  mutate(species = fct_lump(species, n = 3)) %>%
  count(species)

filter(starwars,!is.na(hair_color))%>%
  ggplot(aes(x = hair_color)) + 
    geom_bar() + 
  coord_flip()
starwars %>%
  filter(!is.na(hair_color))%>%
  mutate(hair_color = fct_infreq(hair_color))%>%
  ggplot(aes(x = hair_color)) + 
  geom_bar() + 
  coord_flip()

readr读取文件

readr比baseR读取快10倍
data.table包的fread的速度比readr快1-2倍

library(readr)
read_csv()#: 逗号分隔 (CSV) 文件
read_tsv()#: 制表符分隔的文件
read_delim()#: 一般分隔文件
read_fwf()#: 固定宽度文件
read_table()#:列由空格分隔的表格文件。
read_log()#: 网络日志文件

purrr用于迭代函数,速度非常快

library(purrr)
#purrr的所有函数是C实现的,所以速度非常快。map实现的是for循环,返回值是向量
map() #map的第一个参数可以是向量或数据框。
map_lgl() #生成一个逻辑向量。
map_int() #生成一个整数向量。
map_dbl() #形成一个双向量。
map_chr() #制作一个字符向量。

#示例:
map_int(x,str_count)

x1 <- rnorm(100,mean = 50,sd=15) #产生随机数100个,均值50,标准差15
x2 <- rnorm(100,mean=100)
x3 <- rnorm(100)
xd <- data.frame(x1,x2,x3)
map(xd,sum)
map(xd,sd)

dplyr包的使用:数据处理

library(dplyr)
##数据包 航班 世界发展 棒球数据
if(!require(c("nycflights13", "gapminder", "Lahman")))install.packages(c("nycflights13", "gapminder", "Lahman")) #三个数据包
library(nycflights13)
flights #是2013年美国纽约出发的航班信息
#dplyr常用的函数
#根据其值(filter())选择观察值。
#重新排序行(arrange())。
#按变量名称(select())选择变量。
#使用现有变量(mutate())的功能创建新变量。
#将许多值折叠为一个摘要(summarise())。

April_1st <- filter(flights,month==4,day==1) #查询2013年4月1日出发的航班

filter(flights,!(dep_delay>60|arr_delay>60),month %in% c(4,5,6)) #查看第二季度的出发和到达时间延误均小于等于60min的航班

#查找早上7点前到达和23点之后到达的航班,根据出发时间从早到晚,和到达时间从晚到早排序
filter(flights,arr_time<700 | arr_time>2300) %>% arrange(dep_time,desc(arr_time))

##挑选指定列
select(flights,origin,dest,distance,air_time)

#挑选指定列和指定列之间的列
select(flights, flight:hour)

#挑选除了指定列和指定列之间的列之外所有的列
select(flights, -(flight:hour))
#挑选指定列之外的列
select(flights,-c(year,month,day))

#重命名列名(新的列名在前面,=后是旧的列名)
rename(flights, departtime = dep_time)

#select内部辅助函数
# starts_with("abc"):匹配以“ abc”开头的名称。
# ends_with("xyz"):匹配以“ xyz”结尾的名称。
# contains("ijk"):匹配包含“ ijk”的名称。
# matches("(.)\\1"):选择与正则表达式匹配的变量。该变量与任何包含重复字符的变量匹配。您将了解有关字符串中的正则表达式的更多信息。
# num_range("x", 1:3):匹配x1,x2和x3。

#挑选列名以time结尾的列
select(flights,ends_with("time"))

#挑选包含dep起飞信息的列
select(flights,contains("dep"))

#select和everything联用,用于调整列的顺序(把origin和dest拍到最前面)
select(flights, origin, dest, everything())

#select选择合适的列
flights_sml <- select(flights,
year:day,
ends_with("delay"),
distance,
air_time
)
head(flights_sml)
#mutate增加新的列,同时保留原来的列
mutate(flights_sml,
       gain = dep_delay - arr_delay,
       speed = distance / air_time * 60
)
#transmute是生成新的列,但是不保留原来的列
transmute(flights,
          gain = dep_delay - arr_delay,
          hours = air_time / 60,
          gain_per_hour = gain / hours
)


#near 判断两个数字是否相等
##因为计算机有效数字的问题,无限不循环小数会被截断,所以有时候==并不成立
sqrt(2)^2 == 2 #返回FALSE
near(sqrt(2)^2,2) #返回TRUE

#lead/lag前导值或滞后值

#滚动分析
x <- seq(1,29,by=3)
x
cumsum(x)
#>  [1]   1   5  12  22  35  51  70  92 117 145
cummean(x)
#[1]  1.0  2.5  4.0  5.5  7.0  8.5 10.0 11.5 13.0 14.5

cumprod(x)
cummax(x)
cummin(x)
#分析航班的(到达时间-出发时间)和空中时间的差值,可以看出非飞行时间在机舱内的
### 时间比较长的航班都是长距离航班>1000km,而且主要是目的地是JFK机场的航班。说明JFK的进港时间比较长,机场地勤比较慢
flights %>% arrange(origin) %>% group_by(origin) %>%
  select(contains("time"),dest,distance) %>%
  mutate(groundtime = arr_time - dep_time - air_time) %>%
  arrange(desc(groundtime))

flights %>% head(10) %>%
  identity() %>% rownames()
  ggplot(aes(x=air_time))+
  #geom_histogram()+
  NULL
  geom_boxplot(aes(carrier,flight))


#summaries
summarise(flights,delay=mean(dep_delay,na.rm=TRUE))

#显示出每天的平均出发延误时长
by_day <- group_by(flights,year,month,day)
summarise(by_day,delay = mean(dep_delay,na.rm=TRUE))

#显示出发地和到达地的平均延误时长
by_port <- group_by(flights,origin,dest)
summarise(by_port,delay=mean(dep_delay,na.rm=TRUE))

by_dest <- group_by(flights, dest) #根据出发地分组
delay <- summarise(by_dest,
                   count = n(),
                   dist = mean(distance, na.rm = TRUE), #距离的均值
                   delay = mean(arr_delay, na.rm = TRUE) #到达时延误的均值
  ) %>% filter(count > 20, dest != "HNL") #过滤掉计数少于20,目的地是HNL的数据,HNL距离其他机场太远了

# It looks like delays increase with distance up to ~750 miles
# and then decrease. Maybe as flights get longer there's more
# ability to make up delays in the air?
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
  geom_point(aes(size = count), alpha = 1/3) +
  geom_smooth(se = FALSE)
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'


na.rm = TRUE #是删除含有NA的行
##包含NA的表示航班取消,第一步先过滤掉这部分航班
normal_flight <- flights %>% filter(!is.na(dep_delay),!is.na(arr_delay))

delays <- normal_flight %>%
  group_by(tailnum) %>%
  summarise(delay=mean(arr_delay))
ggplot(data=delays,mapping = aes(x=delay))+geom_freqpoly(binwidth = 10)
##filter是过滤
##arrange是排序,arrange(desc(air_time)) desc是倒序
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,451评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,172评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,782评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,709评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,733评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,578评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,320评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,241评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,686评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,878评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,992评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,715评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,336评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,912评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,040评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,173评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,947评论 2 355

推荐阅读更多精彩内容