本系列主要介绍R语言在数据分析领域的应用包括:
R语言编程基础、R语言可视化、R语言进行数据操作、R语言建模、R语言机器学习算法实现、R语言统计理论方法实现。
本系列会完成下去,请大家多多关注点赞支持,一起学习~
参考资料:
Data Analysis and Prediction Algorithms with R
我们描述了三种主要类型的向量:数字、字符和逻辑。在数据科学项目中,我们经常会遇到日期变量。虽然我们可以用字符串表示日期,例如2017年11月2日,但一旦我们选择了一个被称为“历元”的参考日,就可以通过计算自历元起的天数将其转换为数字。计算机语言通常以1970年1月1日为纪元。例如,2017年1月2日是1,1969年12月31日是-1,2017年11月2日是第17204天。
在R中分析数据时,我们应该如何表示日期和时间?我们接下来看一下具体案例。
library(tidyverse)
library(dslabs)
polls_us_election_2016 %>% head()
state | startdate | enddate | pollster | grade | samplesize | population | rawpoll_clinton | rawpoll_trump | rawpoll_johnson | rawpoll_mcmullin | adjpoll_clinton | adjpoll_trump | adjpoll_johnson | adjpoll_mcmullin | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | U.S. | 2016-11-03 | 2016-11-06 | ABC News/Washington Post | A+ | 2220 | lv | 47.00 | 43.00 | 4.00 | NA | 45.20163 | 41.72430 | 4.626221 | NA |
2 | U.S. | 2016-11-01 | 2016-11-07 | Google Consumer Surveys | B | 26574 | lv | 38.03 | 35.69 | 5.46 | NA | 43.34557 | 41.21439 | 5.175792 | NA |
3 | U.S. | 2016-11-02 | 2016-11-06 | Ipsos | A- | 2195 | lv | 42.00 | 39.00 | 6.00 | NA | 42.02638 | 38.81620 | 6.844734 | NA |
4 | U.S. | 2016-11-04 | 2016-11-07 | YouGov | B | 3677 | lv | 45.00 | 41.00 | 5.00 | NA | 45.65676 | 40.92004 | 6.069454 | NA |
5 | U.S. | 2016-11-03 | 2016-11-06 | Gravis Marketing | B- | 16639 | rv | 47.00 | 43.00 | 3.00 | NA | 46.84089 | 42.33184 | 3.726098 | NA |
6 | U.S. | 2016-11-03 | 2016-11-06 | Fox News/Anderson Robbins Research/Shaw & Company Research | A | 1295 | lv | 48.00 | 44.00 | 3.00 | NA | 49.02208 | 43.95631 | 3.057876 | NA |
class(polls_us_election_2016$startdate)
‘Date’
看看当我们把它们转换成数字时会发生什么:
as.numeric(polls_us_election_2016$startdate) %>% head
因为自动的将上述日期转换成纪元方式定义
as.Date('1970-01-01') %>% as.numeric
0
绘图功能,例如ggplot中的功能,可以知道日期格式。这意味着,例如,散点图可以使用数字表示来确定点的位置,但在标签中包括字符串:
polls_us_election_2016 %>% filter(pollster == "Ipsos" & state =="U.S.") %>%
ggplot(aes(startdate, rawpoll_trump)) +
geom_line()
tidyverse包括通过lubridate包处理日期的功能。
library(lubridate)
我们将随机抽取一个日期数据样本,演示一下如何使用lubridate包
set.seed(1)
dates <- sample(polls_us_election_2016$startdate, 10) %>% sort
dates
可以使用year
,month
,day
分别从日期中截取年、月、日
tibble(date = dates,
month = month(dates),
day = day(dates),
year = year(dates))
date | month | day | year |
---|---|---|---|
2016-05-19 | 5 | 19 | 2016 |
2016-08-12 | 8 | 12 | 2016 |
2016-08-17 | 8 | 17 | 2016 |
2016-08-29 | 8 | 29 | 2016 |
2016-09-28 | 9 | 28 | 2016 |
2016-10-17 | 10 | 17 | 2016 |
2016-10-23 | 10 | 23 | 2016 |
2016-10-25 | 10 | 25 | 2016 |
2016-10-25 | 10 | 25 | 2016 |
2016-10-28 | 10 | 28 | 2016 |
month(dates, label = TRUE)
我们发现上述日期返回的都是中文的,这是因为我们安装的是中文版的R语言,我们可以使用下列代码将时间转换为英文的
Sys.setlocale("LC_TIME", "English")
‘English_United States.1252’
month(dates, label = TRUE)
另外一个函数是将字符串转换为日期型,使用ymd()函数,假定日期的格式是YYYY-MM-DD
的格式
x <- c(20090901,'2009-01-02','2009 01 03','2009-1-4','2009-1,5','created on 2009 1 6','2009 01 $$$ 07')
可以看出上面我定义的x字符串的内容并不是标准的日期,但是ymd函数可以自动尽量将上述转换成下面的格式,具体如下
ymd(x)
更复杂的是,日期通常以不同的格式出现。其中年、月和日的顺序不同。首选的格式是显示年份(全部四位数字)、月份(两位数字),然后是日期,这种格式称为ISO 8601。具体来说,我们使用YYYY-MM-DD,因此如果我们转换字符串,它将按上述方法排序返回。可以看到函数ymd以这种格式返回它们。
但是,如果你遇到“09/01/02”这样的日期怎么办这可能是2002年9月1日、2009年1月2日或2002年1月9日。在这些情况下,检查整个日期向量可以得到具体的日期结果。一旦我们知道了,我们可以使用不同的lubridate包的函数。
例如我们可以使用mdy函数,表示第一个是月份,第二个是日期,第三个是年份
x <- '09/01/02'
mdy(x)
2002-09-01
dmy(x)
2002-01-09
myd(x)
2001-09-02
dym(x)
2001-02-09
同样lubridate
包还可以返回当前日期,并且设定相应的时区
now()
now("GMT")# 表示零时区
[1] "2022-04-23 22:14:18 CST"
[1] "2022-04-23 14:14:18 GMT"
使用OlsonNames()
函数查找可以选择的时区
同样地,我们可以使用hour
,minute
,sencond
分别返回小时、分钟、秒
now() %>% hour()
now() %>% minute()
now() %>% second()
22
27
31.5012230873108
和ymd()函数类似,在这里我们也有hms()函数,返回小时,分钟,秒
x <- c("12:34:56")
hms(x)
12H 34M 56S
注意,这里hms的顺序不能交换,我们还可以使用mdy和hms组合得到一个具体的日期型数据
x <- '12 2 2022 22:33:55'
mdy_hms(x)
[1] "2022-12-02 22:33:55 UTC"
最后再介绍两个十分有用的函数,make_date
和round_date
make_date,可以返回一个日期型数据,例如我们想要生成2022年4月23日的日期数据
make_date(2022,4,23)
2022-04-23
我们还可以生成21世纪20年代的时间序列
make_date(2020:2029)
round_date 函数
从字面意义来看,round意味四舍五入,那么在日期型数据中,它会返回某一日期最近的年份,季度,月份,周等
polls_us_election_2016 %>%
mutate(week = round_date(startdate, "week")) %>%
group_by(week) %>%
summarize(margin = mean(rawpoll_clinton - rawpoll_trump)) %>%
qplot(week, margin, data = .)
R语言数据分析从入门到高级:数据基础处理(mutate、filter、select等)
R语言数据分析从入门到高级:文件读取、导入和复制
R语言数据分析从入门到高级:数据清洗技巧之数据格式转换(包含宽数据与长数据之间的转换)
R语言数据分析从入门到高级:(九)数据清洗技巧之数据表连接