数据科学定义:数据科学(data science)是从数据中发现模式、规律,得到洞见(insight),从而为业界创造商业价值的一套科学方法。
本章着重介绍在数据科学方面常用的两个超级R包,即tidyverse与caret,更为贴近业界的数据科学实践。
为便于执行数据科学项目,RStudio首席科学家Hadley Wickham推出了超级R包tidyverse,包含一系列内在自洽的R包;并因此获得国际统计学会的COPSS奖。
下载并安装tidyverse包
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.5 ✓ purrr 0.3.4
## ✓ tibble 3.1.6 ✓ dplyr 1.0.8
## ✓ tidyr 1.2.0 ✓ stringr 1.4.0
## ✓ readr 2.1.2 ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
结果表明,载入R包tidyverse后,自动加载了8个R包,即ggplot2,tibble,tidyr,readr,purrr,dplyr,stringr,以及forcats(将在下文介绍其中最重要的几个包)。结果还显示,R包dplyr中的filter()函数与lag()函数分别“掩盖”(mask)了同名的R基础函数。如果你想调用R基础函数filter()或lag(),则须使用它们的全称stats::filter()或stats::lag(),从R的基础包stats调用这两个函数。
当复合函数层数比较多时,使用函数套会使得R代码变得不易阅读。
x<- 1:10
y<-round(sum(sin(sqrt(log(x)))),2)
y
## [1] 8.43
一种简化方案:引入一些中间变量
x<-1:10
z<-sqrt(log(x))
w<-sum(sin(z))
y<-round(w,2)
y
## [1] 8.43
以上代码中的“中间对象”(intermediate objects)z与w可能并没有什么意义,而且多用了两行代码。
另一种解决方案:引入管道算子”%>%” 来精简代码
library(tidyverse)
x<-1:10
y<-x %>%log %>% sqrt %>% sin %>% sum %>% round(2)
y
## [1] 8.43
此处管道算子”%>%“可读为“然后”,即“x %>% log”表示将“x”作为参数传递给函数\(log()\). 管道算子优势:可以将一系列管道算子连在一起,构成一个长的管道。比如上例。
不同系统中管道算子的快捷输入法:
1、windows系统%>% 的快捷键:“Ctrl+Shift+M”
2、 Mac系统%>%的快捷键:“command+Shift+M”
管道算子的基本用法主要有以下5种:
1、x%>% y等价于\(f(x)\);
2、x %>% \(f(y)\)等价于\(f(x,y)\);
3、x %>% f %>% \(g\)等价于\(g(f(x))\);
4、x %>% \(f(y,.)\)等价于\(f(y,x)\);
5、x %>% \(f(y,z=.)\)等价于\(f(y,z=x)\);
管道算子使用一般不宜太长,比如超过10步后可考虑通过分拆多个命令来实现,便于纠错。
getwd()
## [1] "/Users/huanghuilin/Desktop/360安全云盘同步版/2022/2022年数据挖掘课程/上机/第二次实验课:tidyverse包的使用"
bank <- read.csv("bank-additional-full.csv",header = T,sep=";")
dim(bank)
## [1] 41188 21
#计算运行此命令的时间
t1<-system.time(read.csv("bank-additional-full.csv",header = T,sep=";"))
为了加快读取数据的速度,我们可以采用R包readr中的函数read_delim()来读取数据
getwd()
## [1] "/Users/huanghuilin/Desktop/360安全云盘同步版/2022/2022年数据挖掘课程/上机/第二次实验课:tidyverse包的使用"
library(readr)
bank <- read_delim("bank-additional-full.csv", col_names = T,delim =";")
#计算运行此命令的时间
t2<-system.time(read_delim("bank-additional-full.csv", col_names = T,delim =";"))
bank
## # A tibble: 41,188 × 21
## age job marital education default housing loan contact month day_of_week
## <dbl> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 56 hous… married basic.4y no no no teleph… may mon
## 2 57 serv… married high.sch… unknown no no teleph… may mon
## 3 37 serv… married high.sch… no yes no teleph… may mon
## 4 40 admi… married basic.6y no no no teleph… may mon
## 5 56 serv… married high.sch… no no yes teleph… may mon
## 6 45 serv… married basic.9y unknown no no teleph… may mon
## 7 59 admi… married professi… no no no teleph… may mon
## 8 41 blue… married unknown unknown no no teleph… may mon
## 9 24 tech… single professi… no yes no teleph… may mon
## 10 25 serv… single high.sch… no yes no teleph… may mon
## # … with 41,178 more rows, and 11 more variables: duration <dbl>,
## # campaign <dbl>, pdays <dbl>, previous <dbl>, poutcome <chr>,
## # emp.var.rate <dbl>, cons.price.idx <dbl>, cons.conf.idx <dbl>,
## # euribor3m <dbl>, nr.employed <dbl>, y <chr>
write_csv(bank,"bank.csv") #利用R包readr中的函数将数据存储
当数据的样本容量特别大时,为了进一步提升数据读取速度,建议使用R包data.table中的fread()函数。
library(data.table)
bank<-fread("bank-additional-full.csv")
t3<-system.time(fread("bank-additional-full.csv"))
rbind(t1,t2,t3)[,1:3]
## user.self sys.self elapsed
## t1 0.351 0.005 0.357
## t2 0.176 0.011 0.097
## t3 0.081 0.002 0.083
总结:可以看出,各个函数读取同一组数据所花费的时间fread()最少,read_delim()次之,read.csv()花费时间最多。
R包tidyverse中的tidyr包可以使得清洗数据变得容易。
library(tidyverse)
table1 #table1为面板数据,且已经为清洁数据
## # A tibble: 6 × 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Afghanistan 2000 2666 20595360
## 3 Brazil 1999 37737 172006362
## 4 Brazil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
#table4a和table4b是table1清洗之前的形式
table4a
## # A tibble: 3 × 3
## country `1999` `2000`
## * <chr> <int> <int>
## 1 Afghanistan 745 2666
## 2 Brazil 37737 80488
## 3 China 212258 213766
table4b
## # A tibble: 3 × 3
## country `1999` `2000`
## * <chr> <int> <int>
## 1 Afghanistan 19987071 20595360
## 2 Brazil 172006362 174504898
## 3 China 1272915272 1280428583
从table4a和table4b可以看出,table4a包含table1中的cases的信息,而table4b包含table1中变量population的信息,变量year的两个取值被作为变量 ’1999’与’2000’使用。
首先利用tidyr包中的gather函数将table4a的两列数据聚集成一个变量cases.
library(tidyverse)
tidy4a<- table4a %>%
gather('1999','2000',key = 'year',value ='cases')
tidy4a
## # A tibble: 6 × 3
## country year cases
## <chr> <chr> <int>
## 1 Afghanistan 1999 745
## 2 Brazil 1999 37737
## 3 China 1999 212258
## 4 Afghanistan 2000 2666
## 5 Brazil 2000 80488
## 6 China 2000 213766
结果显示:生成了两列新变量year与cases. 类似我们可以对table4b进行同样的操作。
library(tidyverse)
tidy4b<- table4b %>%
gather('1999','2000',key = 'year',value ='population')
tidy4b
## # A tibble: 6 × 3
## country year population
## <chr> <chr> <int>
## 1 Afghanistan 1999 19987071
## 2 Brazil 1999 172006362
## 3 China 1999 1272915272
## 4 Afghanistan 2000 20595360
## 5 Brazil 2000 174504898
## 6 China 2000 1280428583
结果显示:生成了两列新变量year与population. 现利用dplyr包中的left_join()函数,将tidy4a与tidy4b进行横向合并,可得完整的整洁数据。
library(dplyr)
left_join(tidy4a,tidy4b)
## # A tibble: 6 × 4
## country year cases population
## <chr> <chr> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Brazil 1999 37737 172006362
## 3 China 1999 212258 1272915272
## 4 Afghanistan 2000 2666 20595360
## 5 Brazil 2000 80488 174504898
## 6 China 2000 213766 1280428583
case1:同一样本占据多行的情形,需要使用函数spread(),将数据“展开”(spread),使得每个观测值仅占一行.
library(tidyverse)
table2
## # A tibble: 12 × 4
## country year type count
## <chr> <int> <chr> <int>
## 1 Afghanistan 1999 cases 745
## 2 Afghanistan 1999 population 19987071
## 3 Afghanistan 2000 cases 2666
## 4 Afghanistan 2000 population 20595360
## 5 Brazil 1999 cases 37737
## 6 Brazil 1999 population 172006362
## 7 Brazil 2000 cases 80488
## 8 Brazil 2000 population 174504898
## 9 China 1999 cases 212258
## 10 China 1999 population 1272915272
## 11 China 2000 cases 213766
## 12 China 2000 population 1280428583
table2 %>%
spread(key=type,value=count)
## # A tibble: 6 × 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Afghanistan 2000 2666 20595360
## 3 Brazil 1999 37737 172006362
## 4 Brazil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
注:1、函数gather()使得宽的数据表格变得更窄、更长。
2、函数spread()使得长的数据表格变得更短、更宽。
case2:多个变量占据同一列,使用函数separate(),将变量rate的信息进行“分离”(separate)
library(tidyverse)
table3
## # A tibble: 6 × 3
## country year rate
## * <chr> <int> <chr>
## 1 Afghanistan 1999 745/19987071
## 2 Afghanistan 2000 2666/20595360
## 3 Brazil 1999 37737/172006362
## 4 Brazil 2000 80488/174504898
## 5 China 1999 212258/1272915272
## 6 China 2000 213766/1280428583
table3 %>%
separate(rate, into = c("cases", "population"), convert = TRUE)
## # A tibble: 6 × 4
## country year cases population
## <chr> <int> <int> <int>
## 1 Afghanistan 1999 745 19987071
## 2 Afghanistan 2000 2666 20595360
## 3 Brazil 1999 37737 172006362
## 4 Brazil 2000 80488 174504898
## 5 China 1999 212258 1272915272
## 6 China 2000 213766 1280428583
其中,变量rate其实包含了两个变量(cases与population)的信息。 参数“convert = TRUE”表示将所得变量cases与population变为更合适的类型,即
函数separate()默认在既非字母、也非数字的字符处切割。也可使用参数“sep=“/””指定在“/”处进行分离。
还可指定分割的具体位置;比如将变量year在其第2个字符之后,切割为变量century与year:
table5 <- table3 %>%
separate(year, into = c("century", "year"), sep = 2)
table5
## # A tibble: 6 × 4
## country century year rate
## <chr> <chr> <chr> <chr>
## 1 Afghanistan 19 99 745/19987071
## 2 Afghanistan 20 00 2666/20595360
## 3 Brazil 19 99 37737/172006362
## 4 Brazil 20 00 80488/174504898
## 5 China 19 99 212258/1272915272
## 6 China 20 00 213766/1280428583
与函数separate()相反的运算为unite(),比如将table5的变量century与year合二为一:
table5 %>% unite(new, century, year,sep="")
## # A tibble: 6 × 3
## country new rate
## <chr> <chr> <chr>
## 1 Afghanistan 1999 745/19987071
## 2 Afghanistan 2000 2666/20595360
## 3 Brazil 1999 37737/172006362
## 4 Brazil 2000 80488/174504898
## 5 China 1999 212258/1272915272
## 6 China 2000 213766/1280428583
其中,参数“sep=““”表示在合并变量取值时,不加任何字符;默认加下划线“_”。
R包tidyverse的dplyr包专门用于做数据变换,包括选取样本、排序、选择变量、生成新变量、合并数据等。 我们以R包nycflights13的flights数据来演示。该数据包含2013年从NewYork三个机场出发的所有336776次航班的信息,共有19个变量。
library(tidyverse)
# install.packages("nycflights13")
library(nycflights13)
flights
## # A tibble: 336,776 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 11 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>
names(flights)
## [1] "year" "month" "day" "dep_time"
## [5] "sched_dep_time" "dep_delay" "arr_time" "sched_arr_time"
## [9] "arr_delay" "carrier" "flight" "tailnum"
## [13] "origin" "dest" "air_time" "distance"
## [17] "hour" "minute" "time_hour"
getwd()
## [1] "/Users/huanghuilin/Desktop/360安全云盘同步版/2022/2022年数据挖掘课程/上机/第二次实验课:tidyverse包的使用"
names<-read.csv("names of flights.csv")
knitr::kable(names)
names | 含义 |
---|---|
dep_time | 起飞时间 |
sched_dep_time | 原定起飞时间 |
dep_delay | 起飞延误 |
arr_time | 降落时间 |
sched_arr_time | 原定降落时间 |
arr_delay | 降落延误 |
carrier | 航空公司 |
flight | 航班号 |
tailnum | 机尾编号 |
origin | 出发地 |
dest | 目的地 |
air_time | 飞行时间 |
distance | 距离 |
hour | 原定几点起飞 |
minute | 原定几分起飞 |
time_hour | 原定起飞日期与时间 |
假设我们仅对1月1日的航班感兴趣,则可以利用dplyr包中的filter()函数进行过滤。
jan1 <-flights %>% filter( month == 1, day == 1)
jan1
## # A tibble: 842 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 832 more rows, and 11 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>
如果我们需要挑选所有11月或12月出发的航班:
flights %>% filter( month == 11 | month == 12)
## # A tibble: 55,403 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 11 1 5 2359 6 352 345
## 2 2013 11 1 35 2250 105 123 2356
## 3 2013 11 1 455 500 -5 641 651
## 4 2013 11 1 539 545 -6 856 827
## 5 2013 11 1 542 545 -3 831 855
## 6 2013 11 1 549 600 -11 912 923
## 7 2013 11 1 550 600 -10 705 659
## 8 2013 11 1 554 600 -6 659 701
## 9 2013 11 1 554 600 -6 826 827
## 10 2013 11 1 554 600 -6 749 751
## # … with 55,393 more rows, and 11 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>
#另一种等价表达:
flights %>% filter( month %in% c(11, 12))
## # A tibble: 55,403 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 11 1 5 2359 6 352 345
## 2 2013 11 1 35 2250 105 123 2356
## 3 2013 11 1 455 500 -5 641 651
## 4 2013 11 1 539 545 -6 856 827
## 5 2013 11 1 542 545 -3 831 855
## 6 2013 11 1 549 600 -11 912 923
## 7 2013 11 1 550 600 -10 705 659
## 8 2013 11 1 554 600 -6 659 701
## 9 2013 11 1 554 600 -6 826 827
## 10 2013 11 1 554 600 -6 749 751
## # … with 55,393 more rows, and 11 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>
#如果需要挑选上半年的数据:
flights %>% filter(month %in% 1:6)
## # A tibble: 166,158 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 166,148 more rows, and 11 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>
如果需要对观测值进行排序,可使用dplyr包的arrange()函数。 首先,将flights数据按照年、月、日进行升序排列:
flights %>% arrange(year,month,day)
## # A tibble: 336,776 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 11 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>
其次,按照dep_delay(起飞延误)进行升序排列,可输入命令:
flights %>% arrange(dep_delay)
## # A tibble: 336,776 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 12 7 2040 2123 -43 40 2352
## 2 2013 2 3 2022 2055 -33 2240 2338
## 3 2013 11 10 1408 1440 -32 1549 1559
## 4 2013 1 11 1900 1930 -30 2233 2243
## 5 2013 1 29 1703 1730 -27 1947 1957
## 6 2013 8 9 729 755 -26 1002 955
## 7 2013 10 23 1907 1932 -25 2143 2143
## 8 2013 3 30 2030 2055 -25 2213 2250
## 9 2013 3 2 1431 1455 -24 1601 1631
## 10 2013 5 5 934 958 -24 1225 1309
## # … with 336,766 more rows, and 11 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>
若按照dep_delay(起飞延误)进行降序排列,可输入命令:
flights %>% arrange(desc(dep_delay))
## # A tibble: 336,776 × 19
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 9 641 900 1301 1242 1530
## 2 2013 6 15 1432 1935 1137 1607 2120
## 3 2013 1 10 1121 1635 1126 1239 1810
## 4 2013 9 20 1139 1845 1014 1457 2210
## 5 2013 7 22 845 1600 1005 1044 1815
## 6 2013 4 10 1100 1900 960 1342 2211
## 7 2013 3 17 2321 810 911 135 1020
## 8 2013 6 27 959 1900 899 1236 2226
## 9 2013 7 22 2257 759 898 121 1026
## 10 2013 12 5 756 1700 896 1058 2020
## # … with 336,766 more rows, and 11 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>
结果显示,dep_delay的最大值为1301,这意味着延误1301分钟(即21小时41分钟)才起飞。
如果我们只想选择部分变量,可使用dplyr包的select()函数. 首先,只选择flights数据集中的year、month与day这三个变量:
flights %>% select(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
## 7 2013 1 1
## 8 2013 1 1
## 9 2013 1 1
## 10 2013 1 1
## # … with 336,766 more rows
#上述命令和下面的命令等价:
flights %>% select(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
## 7 2013 1 1
## 8 2013 1 1
## 9 2013 1 1
## 10 2013 1 1
## # … with 336,766 more rows
若选取year、month与day变量以外的所有变量,可输入命令:
flights %>% select(-(year:day))
## # A tibble: 336,776 × 16
## dep_time sched_dep_time dep_delay arr_time sched_arr_time arr_delay carrier
## <int> <int> <dbl> <int> <int> <dbl> <chr>
## 1 517 515 2 830 819 11 UA
## 2 533 529 4 850 830 20 UA
## 3 542 540 2 923 850 33 AA
## 4 544 545 -1 1004 1022 -18 B6
## 5 554 600 -6 812 837 -25 DL
## 6 554 558 -4 740 728 12 UA
## 7 555 600 -5 913 854 19 B6
## 8 557 600 -3 709 723 -14 EV
## 9 557 600 -3 838 846 -8 B6
## 10 558 600 -2 753 745 8 AA
## # … with 336,766 more rows, and 9 more variables: flight <int>, tailnum <chr>,
## # origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>, hour <dbl>,
## # minute <dbl>, time_hour <dttm>
其次,还可以使用select()函数调整变量在数据框中的排序。 假设希望将变量time_hour与air_time排到所有变量的前面,可输入命令:
select (flights,time_hour,air_time,everything())
## # A tibble: 336,776 × 19
## time_hour air_time year month day dep_time sched_dep_time
## <dttm> <dbl> <int> <int> <int> <int> <int>
## 1 2013-01-01 05:00:00 227 2013 1 1 517 515
## 2 2013-01-01 05:00:00 227 2013 1 1 533 529
## 3 2013-01-01 05:00:00 160 2013 1 1 542 540
## 4 2013-01-01 05:00:00 183 2013 1 1 544 545
## 5 2013-01-01 06:00:00 116 2013 1 1 554 600
## 6 2013-01-01 05:00:00 150 2013 1 1 554 558
## 7 2013-01-01 06:00:00 158 2013 1 1 555 600
## 8 2013-01-01 06:00:00 53 2013 1 1 557 600
## 9 2013-01-01 06:00:00 140 2013 1 1 557 600
## 10 2013-01-01 06:00:00 138 2013 1 1 558 600
## # … with 336,766 more rows, and 12 more variables: 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>
参数everything()表示所有其他变量。
如果要改变变量名,可以利用dplyr包中的rename()函数。 假设我们要将变量sched_dep_time重新命令为s_dep_time:
flights %>% rename(s_dep_time=sched_dep_time)
## # A tibble: 336,776 × 19
## year month day dep_time s_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 11 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>
如果要根据原有变量生成新的变量,可以用dplyr包中的mutate()函数,而新生成的变量将排在最后。 为了演示方便,我们先用select()函数选择少数变量,并将所得数据集记为f1:
f1<- flights %>% select(ends_with("delay"),distance,air_time)
f1
## # A tibble: 336,776 × 4
## dep_delay arr_delay distance air_time
## <dbl> <dbl> <dbl> <dbl>
## 1 2 11 1400 227
## 2 4 20 1416 227
## 3 2 33 1089 160
## 4 -1 -18 1576 183
## 5 -6 -25 762 116
## 6 -4 12 719 150
## 7 -5 19 1065 158
## 8 -3 -14 229 53
## 9 -3 -8 944 140
## 10 -2 8 733 138
## # … with 336,766 more rows
其中,参数“ends_with(“delay”)”表示以“delay”结尾的变量。 现在,我们来定义两个新变量gain≈和speed分别表示追回多少时间和飞行速度,可输入命令:
f1 %>% mutate(gain=dep_delay-arr_delay, speed=distance/air_time*60)
## # A tibble: 336,776 × 6
## dep_delay arr_delay distance air_time gain speed
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2 11 1400 227 -9 370.
## 2 4 20 1416 227 -16 374.
## 3 2 33 1089 160 -31 408.
## 4 -1 -18 1576 183 17 517.
## 5 -6 -25 762 116 19 394.
## 6 -4 12 719 150 -16 288.
## 7 -5 19 1065 158 -24 404.
## 8 -3 -14 229 53 11 259.
## 9 -3 -8 944 140 5 405.
## 10 -2 8 733 138 -10 319.
## # … with 336,766 more rows
变量distance以英里为单位,air_time以分钟为单位,因此speed=distance/air_time*60表示每小时飞行多少英里。
我们可以利用dplyr包中的summarize()函数计算一些样本数据的概括性的统计指标。 比如:计算样本中变量dep_delay(起飞延误)的平均值,并将数据框命名为delay.
flights %>% summarize(delay=mean(dep_delay,na.rm=TRUE))
## # A tibble: 1 × 1
## delay
## <dbl>
## 1 12.6
其中函数mean()的参数na.rm=TRUE表示在计算平均值时,去掉缺失值。
函数summariz()更重要的一个功能是能实现分组计算统计指标。
m_delay<-flights %>% group_by(month) %>% summarize(delay=mean(dep_delay,na.rm=TRUE))
m_delay %>% arrange(delay) #按照delay的升序排列
## # A tibble: 12 × 2
## month delay
## <int> <dbl>
## 1 11 5.44
## 2 10 6.24
## 3 9 6.72
## 4 1 10.0
## 5 2 10.8
## 6 8 12.6
## 7 5 13.0
## 8 3 13.2
## 9 4 13.9
## 10 12 16.6
## 11 6 20.8
## 12 7 21.7
m_delay %>% arrange(desc(delay)) #按照delay的降序排列
## # A tibble: 12 × 2
## month delay
## <int> <dbl>
## 1 7 21.7
## 2 6 20.8
## 3 12 16.6
## 4 4 13.9
## 5 3 13.2
## 6 5 13.0
## 7 8 12.6
## 8 2 10.8
## 9 1 10.0
## 10 9 6.72
## 11 10 6.24
## 12 11 5.44
结果变量,结果表明,在一年之中,延误最严重的月份是6月和7月,其次是12月,都是旅行旺季。
在实际应用中我们往往需要将来自不同渠道的数据框进行有意义的合并。 R包dplyr包中的left_join()函数可以实现数据合并功能,且其速度远远快于R基础函数merge(). 继续以R包nycflights13为例,此R包除了flights数据外,还有其他相关数据,比如airlines提供航空公司的全称:
library(nycflights13)
airlines
## # A tibble: 16 × 2
## carrier name
## <chr> <chr>
## 1 9E Endeavor Air Inc.
## 2 AA American Airlines Inc.
## 3 AS Alaska Airlines Inc.
## 4 B6 JetBlue Airways
## 5 DL Delta Air Lines Inc.
## 6 EV ExpressJet Airlines Inc.
## 7 F9 Frontier Airlines Inc.
## 8 FL AirTran Airways Corporation
## 9 HA Hawaiian Airlines Inc.
## 10 MQ Envoy Air
## 11 OO SkyWest Airlines Inc.
## 12 UA United Air Lines Inc.
## 13 US US Airways Inc.
## 14 VX Virgin America
## 15 WN Southwest Airlines Co.
## 16 YV Mesa Airlines Inc.
结果显示,数据框airlines中包含16家航空公司的简称(carrier)与全称(name)。 R包dplyr中最常用的合并函数为left_join(),其基本格式为:
left_join(x,y,by=“var”)
此命令表示,将数据框x与数据框y合并,合并方式为保留数据框x中的所有行,同时根据变量var进行匹配,把数据框y的变量合并到数据框x.进行匹配所用的变量var称为关键词。
示例:将数据框airlines的变量name作为一个变量加到数据框flights.
library(nycflights13)
names(flights)
## [1] "year" "month" "day" "dep_time"
## [5] "sched_dep_time" "dep_delay" "arr_time" "sched_arr_time"
## [9] "arr_delay" "carrier" "flight" "tailnum"
## [13] "origin" "dest" "air_time" "distance"
## [17] "hour" "minute" "time_hour"
names(airlines)
## [1] "carrier" "name"
new<-left_join(flights,airlines,by="carrier")
dim<-rbind.data.frame(dim(flights),dim(airlines),dim(new)) #合并维度向量
names(dim)=c("nrow","ncolumn")
knitr::kable(dim)
nrow | ncolumn |
---|---|
336776 | 19 |
16 | 2 |
336776 | 20 |
names(new)
## [1] "year" "month" "day" "dep_time"
## [5] "sched_dep_time" "dep_delay" "arr_time" "sched_arr_time"
## [9] "arr_delay" "carrier" "flight" "tailnum"
## [13] "origin" "dest" "air_time" "distance"
## [17] "hour" "minute" "time_hour" "name"
new[,c(10,18:20)]
## # A tibble: 336,776 × 4
## carrier minute time_hour name
## <chr> <dbl> <dttm> <chr>
## 1 UA 15 2013-01-01 05:00:00 United Air Lines Inc.
## 2 UA 29 2013-01-01 05:00:00 United Air Lines Inc.
## 3 AA 40 2013-01-01 05:00:00 American Airlines Inc.
## 4 B6 45 2013-01-01 05:00:00 JetBlue Airways
## 5 DL 0 2013-01-01 06:00:00 Delta Air Lines Inc.
## 6 UA 58 2013-01-01 05:00:00 United Air Lines Inc.
## 7 B6 0 2013-01-01 06:00:00 JetBlue Airways
## 8 EV 0 2013-01-01 06:00:00 ExpressJet Airlines Inc.
## 9 B6 0 2013-01-01 06:00:00 JetBlue Airways
## 10 AA 0 2013-01-01 06:00:00 American Airlines Inc.
## # … with 336,766 more rows
write.csv(airlines,"airlines.csv")
write.csv(flights,"flights.csv")
write.csv(new,"flights_airlines.csv")
在使用函数left_join()时,如果省略参数by=“carrier”,则默认使用两个数据框的所有变量进行匹配,称为”自然合并”。
示例:R包nycflights13还提供了数据框weather,提供纽约三个机场每个小时的天气情况数据,我们将其与flights数据进行自然合并:
library(nycflights13)
weather
## # A tibble: 26,115 × 15
## origin year month day hour temp dewp humid wind_dir wind_speed
## <chr> <int> <int> <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 EWR 2013 1 1 1 39.0 26.1 59.4 270 10.4
## 2 EWR 2013 1 1 2 39.0 27.0 61.6 250 8.06
## 3 EWR 2013 1 1 3 39.0 28.0 64.4 240 11.5
## 4 EWR 2013 1 1 4 39.9 28.0 62.2 250 12.7
## 5 EWR 2013 1 1 5 39.0 28.0 64.4 260 12.7
## 6 EWR 2013 1 1 6 37.9 28.0 67.2 240 11.5
## 7 EWR 2013 1 1 7 39.0 28.0 64.4 240 15.0
## 8 EWR 2013 1 1 8 39.9 28.0 62.2 250 10.4
## 9 EWR 2013 1 1 9 39.9 28.0 62.2 260 15.0
## 10 EWR 2013 1 1 10 41 28.0 59.6 260 13.8
## # … with 26,105 more rows, and 5 more variables: wind_gust <dbl>, precip <dbl>,
## # pressure <dbl>, visib <dbl>, time_hour <dttm>
new<-left_join(flights,weather)
new
## # A tibble: 336,776 × 28
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 20 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>,
## # temp <dbl>, dewp <dbl>, humid <dbl>, wind_dir <dbl>, wind_speed <dbl>,
## # wind_gust <dbl>, precip <dbl>, pressure <dbl>, visib <dbl>
dim<-rbind.data.frame(dim(flights),dim(weather),dim(new))
names(dim)=c("nrow","ncolumn")
knitr::kable(dim)
nrow | ncolumn |
---|---|
336776 | 19 |
26115 | 15 |
336776 | 28 |
write.csv(weather,"weather.csv")
write.csv(new,"flights_weather.csv")
结果显示,已将天体变量合并入数据框。
进一步地,R包nycflights13还包含另一数据框airports,提供有关机场的信息。我们将其与flights数据集合并,合并标准为 数据集flights中的dest取值与数据框airports的变量faa取值相同:
library(nycflights13)
airports
## # A tibble: 1,458 × 8
## faa name lat lon alt tz dst tzone
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr> <chr>
## 1 04G Lansdowne Airport 41.1 -80.6 1044 -5 A America/…
## 2 06A Moton Field Municipal Airport 32.5 -85.7 264 -6 A America/…
## 3 06C Schaumburg Regional 42.0 -88.1 801 -6 A America/…
## 4 06N Randall Airport 41.4 -74.4 523 -5 A America/…
## 5 09J Jekyll Island Airport 31.1 -81.4 11 -5 A America/…
## 6 0A9 Elizabethton Municipal Airport 36.4 -82.2 1593 -5 A America/…
## 7 0G6 Williams County Airport 41.5 -84.5 730 -5 A America/…
## 8 0G7 Finger Lakes Regional Airport 42.9 -76.8 492 -5 A America/…
## 9 0P2 Shoestring Aviation Airfield 39.8 -76.6 1000 -5 U America/…
## 10 0S9 Jefferson County Intl 48.1 -123. 108 -8 A America/…
## # … with 1,448 more rows
new<-left_join(flights,airports,by=c("dest"="faa"))
new
## # A tibble: 336,776 × 26
## year month day dep_time sched_dep_time dep_delay arr_time sched_arr_time
## <int> <int> <int> <int> <int> <dbl> <int> <int>
## 1 2013 1 1 517 515 2 830 819
## 2 2013 1 1 533 529 4 850 830
## 3 2013 1 1 542 540 2 923 850
## 4 2013 1 1 544 545 -1 1004 1022
## 5 2013 1 1 554 600 -6 812 837
## 6 2013 1 1 554 558 -4 740 728
## 7 2013 1 1 555 600 -5 913 854
## 8 2013 1 1 557 600 -3 709 723
## 9 2013 1 1 557 600 -3 838 846
## 10 2013 1 1 558 600 -2 753 745
## # … with 336,766 more rows, and 18 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>,
## # name <chr>, lat <dbl>, lon <dbl>, alt <dbl>, tz <dbl>, dst <chr>,
## # tzone <chr>
write.csv(airports,"airports.csv")
write.csv(new,"flights_airports.csv")
上述参数by=c(“dest”=“faa”)表明在合并时第一个数据框的变量dest取值须与第2个数据框的变量faa的取值相同,以此作为匹配标准。
R包dplyr中除了常用的left_join()之外,还有如下表所示:
getwd()
## [1] "/Users/huanghuilin/Desktop/360安全云盘同步版/2022/2022年数据挖掘课程/上机/第二次实验课:tidyverse包的使用"
join<-read.csv("dplyr包中数据合并的函数及功能.csv",header=T)
knitr::kable(join)
函数名 | 功能 |
---|---|
left_join(x,y) | 保留数据框 x 中的所有观测值信息 |
right_join(x,y) | 保留数据框 y 中的所有观测值信息 |
full_join(x,y) | 保留数据框 x 和 y 中的所有观测值信息 |
上述函数具体用法可以查询帮助文档。