首页 > > > R语言数据操作:练习题跟帖2
作者:黄天元,复旦大学博士在读,热爱数据科学与开源工具(R),致力于利用数据科学迅速积累行业经验优势和科学知识发现,涉猎内容包括但不限于信息计量、机器学习、数据可视化、应用统计建模、知识图谱等,著有《R语言数据高效处理指南》(《R语言数据高效处理指南》(黄天元)【摘要 书评 试读】- 京东图书,《R语言数据高效处理指南》(黄天元)【简介_书评_在线阅读】 - 当当图书)。知乎专栏:R语言数据挖掘。邮箱:huang.tian-yuan@qq.com.欢迎合作交流。
延续上一次的练习提跟帖:
这次新的内容(R练习50题 - 第二期)出来了,我们继续用dtplyr来对data.table的代码进行优化,并且尝试告诉大家为什么要这么做。话不多说,先上代码:
# 3.每天每个交易所上涨、下跌的股票各有多少?
# data.table
data[, .(num = uniqueN(symbol)),
keyby = .(date,
exchange = str_sub(symbol, start = -2, end = -1),
updown = ifelse(close - pre_close > 0, "UP", "DOWN"))
]
# dtplyr
data %>%
lazy_dt() %>%
mutate(exchange = str_sub(symbol, start = -2, end = -1)) %>%
mutate(updown = ifelse(close - pre_close > 0, "UP", "DOWN")) %>%
group_by(date,exchange) %>%
count(updown,name = "num") %>%
as_tibble()
# 4.沪深300成分股中,每天上涨、下跌的股票各有多少?
# data.table
data[index_w300 > 0,
.(num = uniqueN(symbol)),
keyby = .(date, updown = ifelse(close - pre_close > 0, "UP", "DOWN"))
]
# dtplyr
data %>%
lazy_dt() %>%
filter(index_w300 > 0) %>%
mutate(updown = ifelse(close - pre_close > 0, "UP", "DOWN")) %>%
group_by(date) %>%
count(updown) %>%
as_tibble()
# 5.每天每个行业各有多少只股票?
# data.table
data[, .(stk_num = uniqueN(symbol)),
keyby = .(date, industry)
]
# dtplyr
data %>%
lazy_dt() %>%
group_by(date,industry) %>%
distinct(symbol) %>%
summarise(stk_num = n()) %>%
tibble()
# 7.每天涨幅超过5%、跌幅超过5%的股票各有多少?
# data.table
data[, ':='(ret = (close - pre_close)/pre_close)
][ret > 0.05 | ret < -0.05,
.(symbol_amount = uniqueN(symbol)),
keyby = .(date, updown = ifelse(ret > 0.05, "up5%+", "down5%+"))
]
# dtplyr
data %>%
lazy_dt() %>%
mutate(ret = (close - pre_close)/pre_close) %>%
filter(ret > 0.05 | ret < -0.05) %>%
mutate(updown = ifelse(ret > 0.05, "up5%+", "down5%+")) %>%
group_by(date,updown) %>%
distinct(symbol) %>%
summarise(symbol_amount = n()) %>%
as_tibble()
重点解释以下几点:
1、为什么dtplyr总是比data.table代码长?
首先,为了转化为data.table的代码,我们总是在开端设置了惰性评估(lazy evaluation)函数,即为lazy_dt。
其次,为了把数据收集回来(collect),总是在最后加上as_tibble。
最后而最重要的是,dplyr的核心思想就是把任何一个复杂的工序,分解成最小简单组分,然后拼接到一起,完成一个大的任务。这不仅仅是在编程中,而是在任何大型的工程中都极为重要的思想。而把复杂的东西一大团浆糊一样糊在[i,j,by]中,则让人容易迷乱。一个简单的思考:data.table的[i,j,by]模式总是先i后by最后j,如果我告诉大家做事情要先1后3再2,那是足够2的一件事情...
2、如果你还是想写data.table但是不知道怎么写,怎么办?
上面的代码,大家不写as_tibble试试,马上获得机器翻译的data.table代码,十拿九稳的准确。所以会dplyr的同学甚至可以不学data.table,马上获得data.table的速度。例子如下:
# 3.每天每个交易所上涨、下跌的股票各有多少?
# dtplyr
data %>%
lazy_dt() %>%
mutate(exchange = str_sub(symbol, start = -2, end = -1)) %>%
mutate(updown = ifelse(close - pre_close > 0, "UP", "DOWN")) %>%
group_by(date,exchange) %>%
count(updown,name = "num") %>%
Source: local data table [?? x 4]
Call: copy(`_DT21`)[, `:=`(exchange = str_sub(symbol, start = -2, end = -1))][,
`:=`(updown = ifelse(close - pre_close > 0, "UP", "DOWN"))][,
.(num = .N), keyby = .(date, exchange, updown)]
date exchange updown num
<int> <chr> <chr> <int>
1 20120104 SH DOWN 836
2 20120104 SH UP 85
3 20120104 SZ DOWN 1293
4 20120104 SZ UP 106
5 20120105 SH DOWN 847
6 20120105 SH UP 74
# Use as.data.table()/as.data.frame()/as_tibble() to access resultsCall中就是翻译好的data.table代码。
总结来说,data.table的设计违反了程序自上而下的顺序结构(132),很难让人有一步一步清晰往下 处理的既视感,而dplyr则可以把所有任务分解为最小可操作单元,这是一个非常大的进步。这提高了代码的可读性,降低初学者的学习成本和用户的代码交流成本。事实上,我们看dplyr的动词代码,甚至比直接看文字来描述数据操作理解得更快,这打破了思维逻辑与实现操作的壁垒。
下面,我手撕一个“具有争议”的第6题,让大家看看它的威力。第6题的描述如下:
6. 股票数最大的行业和总成交额最大的行业是否总是同一个行业?
这句话先这么理解,“A行业”和“B行业”是不是“总是”同一个行业?
那么我们需要先求得“A行业”和“B行业”,因为问了是不是“总是”,所以有一个时间的概念在里面,需要按照日期分组来求“A行业”和“B行业”。
A行业,股票数最大的行业,这样求:
# 每天股票数最大行业
data %>%
lazy_dt() %>%
distinct(date,industry,symbol) %>%
count(date,industry,sort = T) %>%
group_by(date) %>%
slice(1) %>%
as_tibble() -> AB行业,每天成交额最大的行业,这样求:
# 每天成交额最大的行业
data %>%
lazy_dt() %>%
group_by(date) %>%
count(industry,wt = amount,sort = T) %>%
slice(1) %>%
as_tibble() -> B是不是同一行业,这样求:
A %>%
inner_join(B,by = "date") %>%
mutate(same = industry.x == industry.y) -> same_or_not看看具体情况:
same_or_not %>%
pull(same) %>%
table()
.
FALSE TRUE
102 15 也就是说在117个交易日中,用15天是同一行业,其余不是同一行业。
代码不一定短,但是肯定是无比地清晰。所谓data.table短小的代码其实都是在大量人类掉头发试错之后的短小,而上面这些清晰的代码其实写起来并不会花特别长的时间(也可能我已经过分熟练了...)。
最后,这个系列的代码我会统一上传到Github(hope-data-science/R_ETL)供大家玩耍,不过数据太大我就不重复上传了,大家可以去原始网站(renkun-ken/r-data-practice)来下载。
原文作者:;如有侵权,请联系管理员删除。