R语言里有诸多处理数据的函数包。因为习惯使用数据库sql
的缘故平时处理数据用sqldf
这个包调用sql命令比较多一些。但是R语言作为数据分析工具,受很多数据分析人员的偏爱他还是有一定原因的。他自己拥有很多高效处理转换数据的表dplyr
就是其中一个,今天本文从这两个包出发,从数据筛选、数据排序、选择变量、增加变量、数据排序
等五个角度对比一下这两个函数包。
本人是王者荣耀忠实玩家,自2016年上大学入坑,断断续续的玩想来已有4年半,今天就构造的数据就以王者荣耀为背景。
当然最开始导入本文所需要的两个主角包。
# 包的导入
> library(dplyr)
> library(sqldf)
注:dplyr包的载入会覆盖一下其他包的函数,具体解决措施见R语言入门——包的函数被覆盖,里面有应对办法。
# 构造数据
> Data <- data.frame(
+ 英雄 = c("后裔", "孙尚香", "狄仁杰", "李元芳", "安琪拉", "张良", "不知火舞", "貂蝉"),
+ 职业 = c("射手", "射手", "射手", "射手", "法师", "法师", "法师", "法师"),
+ 熟练等级 = c(5, 5, 5, 4, 5, 4, 4, 3),
+ 使用频次 = c(856, 211, 324, 75, 2324, 755, 644, 982),
+ 胜率 = c(sqrt(0.64)^2, (1:7)/10)
+ )
> Data
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
4 李元芳 射手 4 75 0.30
5 安琪拉 法师 5 2324 0.40
6 张良 法师 4 755 0.50
7 不知火舞 法师 4 644 0.60
8 貂蝉 法师 3 982 0.70
共有5个变量,8次观测。
filter(数据, 逻辑语句)
> filter(Data, 英雄 == "不知火舞")
英雄 职业 熟练等级 使用频次 胜率
1 不知火舞 法师 4 644 0.6
> filter(Data, 职业 == "法师")
英雄 职业 熟练等级 使用频次 胜率
1 安琪拉 法师 5 2324 0.4
2 张良 法师 4 755 0.5
3 不知火舞 法师 4 644 0.6
4 貂蝉 法师 3 982 0.7
> filter(Data, 职业 == "射手"&熟练等级 == 5)
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
> filter(Data, 胜率 == 0.1)
英雄 职业 熟练等级 使用频次 胜率
1 孙尚香 射手 5 211 0.1
> filter(Data, 胜率 == 0.64)
[1] 英雄 职业 熟练等级 使用频次 胜率
<0 行> (或0-长度的row.names)
> filter(Data, between(胜率, 0.1, 0.4))
英雄 职业 熟练等级 使用频次 胜率
1 孙尚香 射手 5 211 0.1
2 狄仁杰 射手 5 324 0.2
3 李元芳 射手 4 75 0.3
4 安琪拉 法师 5 2324 0.4
> filter(Data, near(胜率, 0.64))
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
注:在使用filter
函数进行筛选数据时,注意和between
,near
函数的结合。该函数与基础包里subset
函数功能相似。
between
函数是用来取连续的连续变量,near
函数是用来取浮点型的数据。
> near(sqrt(0.64)^2, 0.64)
[1] TRUE
> sqrt(0.64)^2 == 0.64
[1] FALSE
包sqldf
也可以通过下面命令完成上述的相同的任务:
> sqldf("
+ select * from Data where 英雄 == '不知火舞'
+ ")
英雄 职业 熟练等级 使用频次 胜率
1 不知火舞 法师 4 644 0.6
> sqldf("
+ select * from Data where 职业 == '射手' and 熟练等级 == 5
+ ")
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
> sqldf("
+ select * from Data where 胜率 between 0.1 and 0.4
+ ")
英雄 职业 熟练等级 使用频次 胜率
1 孙尚香 射手 5 211 0.1
2 狄仁杰 射手 5 324 0.2
3 李元芳 射手 4 75 0.3
4 安琪拉 法师 5 2324 0.4
> sqldf("
+ select * from Data where 胜率 == 0.64
+ ")
[1] 英雄 职业 熟练等级 使用频次 胜率
<0 行> (或0-长度的row.names)
> sqldf("
+ select * from Data where 胜率 between (0.64-0.0001) and (0.64+0.0001)
+ ")
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
> Data
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
4 李元芳 射手 4 75 0.30
5 安琪拉 法师 5 2324 0.40
6 张良 法师 4 755 0.50
7 不知火舞 法师 4 644 0.60
8 貂蝉 法师 3 982 0.70
> arrange(Data, 熟练等级) # 默认升序
英雄 职业 熟练等级 使用频次 胜率
1 貂蝉 法师 3 982 0.70
2 李元芳 射手 4 75 0.30
3 张良 法师 4 755 0.50
4 不知火舞 法师 4 644 0.60
5 后裔 射手 5 856 0.64
6 孙尚香 射手 5 211 0.10
7 狄仁杰 射手 5 324 0.20
8 安琪拉 法师 5 2324 0.40
> arrange(Data, desc(熟练等级)) # 降序
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
4 安琪拉 法师 5 2324 0.40
5 李元芳 射手 4 75 0.30
6 张良 法师 4 755 0.50
7 不知火舞 法师 4 644 0.60
8 貂蝉 法师 3 982 0.70
> # 熟练等级降序,使用频次升序
> arrange(Data, desc(熟练等级), 使用频次 )
英雄 职业 熟练等级 使用频次 胜率
1 孙尚香 射手 5 211 0.10
2 狄仁杰 射手 5 324 0.20
3 后裔 射手 5 856 0.64
4 安琪拉 法师 5 2324 0.40
5 李元芳 射手 4 75 0.30
6 不知火舞 法师 4 644 0.60
7 张良 法师 4 755 0.50
8 貂蝉 法师 3 982 0.70
> sqldf("
+ select * from Data order by 熟练等级
+ ") # 默认升序
英雄 职业 熟练等级 使用频次 胜率
1 貂蝉 法师 3 982 0.70
2 李元芳 射手 4 75 0.30
3 张良 法师 4 755 0.50
4 不知火舞 法师 4 644 0.60
5 后裔 射手 5 856 0.64
6 孙尚香 射手 5 211 0.10
7 狄仁杰 射手 5 324 0.20
8 安琪拉 法师 5 2324 0.40
> sqldf("
+ select * from Data order by 熟练等级 desc
+ ") # 降序
英雄 职业 熟练等级 使用频次 胜率
1 后裔 射手 5 856 0.64
2 孙尚香 射手 5 211 0.10
3 狄仁杰 射手 5 324 0.20
4 安琪拉 法师 5 2324 0.40
5 李元芳 射手 4 75 0.30
6 张良 法师 4 755 0.50
7 不知火舞 法师 4 644 0.60
8 貂蝉 法师 3 982 0.70
> # 熟练等级降序,使用频次升序
> sqldf("
+ select * from Data order by 熟练等级 desc, 使用频次
+ ")
英雄 职业 熟练等级 使用频次 胜率
1 孙尚香 射手 5 211 0.10
2 狄仁杰 射手 5 324 0.20
3 后裔 射手 5 856 0.64
4 安琪拉 法师 5 2324 0.40
5 李元芳 射手 4 75 0.30
6 不知火舞 法师 4 644 0.60
7 张良 法师 4 755 0.50
8 貂蝉 法师 3 982 0.70
函数select
在选择列的时候可以与正则表达式进行结合。这里给出例子进行说明。
> select(Data, 英雄, 熟练等级, 胜率)
英雄 熟练等级 胜率
1 后裔 5 0.64
2 孙尚香 5 0.10
3 狄仁杰 5 0.20
4 李元芳 4 0.30
5 安琪拉 5 0.40
6 张良 4 0.50
7 不知火舞 4 0.60
8 貂蝉 3 0.70
> select(Data, -使用频次)
英雄 职业 熟练等级 胜率
1 后裔 射手 5 0.64
2 孙尚香 射手 5 0.10
3 狄仁杰 射手 5 0.20
4 李元芳 射手 4 0.30
5 安琪拉 法师 5 0.40
6 张良 法师 4 0.50
7 不知火舞 法师 4 0.60
8 貂蝉 法师 3 0.70
> # 正则表达式的结合
> select(Data, starts_with("英")) # “英”开头
英雄
1 后裔
2 孙尚香
3 狄仁杰
4 李元芳
5 安琪拉
6 张良
7 不知火舞
8 貂蝉
> select(Data, ends_with("雄")) # “雄”结尾
英雄
1 后裔
2 孙尚香
3 狄仁杰
4 李元芳
5 安琪拉
6 张良
7 不知火舞
8 貂蝉
> select(Data, contains("等")) # 名字中含有“等”
熟练等级
1 5
2 5
3 5
4 4
5 5
6 4
7 4
8 3
> sqldf("
+ select 英雄, 熟练等级, 胜率 from Data
+ ")
英雄 熟练等级 胜率
1 后裔 5 0.64
2 孙尚香 5 0.10
3 狄仁杰 5 0.20
4 李元芳 4 0.30
5 安琪拉 5 0.40
6 张良 4 0.50
7 不知火舞 4 0.60
8 貂蝉 3 0.70
> mutate(Data, rew等级 = 熟练等级 + 1)
英雄 职业 熟练等级 使用频次 胜率 rew等级
1 后裔 射手 5 856 0.64 6
2 孙尚香 射手 5 211 0.10 6
3 狄仁杰 射手 5 324 0.20 6
4 李元芳 射手 4 75 0.30 5
5 安琪拉 法师 5 2324 0.40 6
6 张良 法师 4 755 0.50 5
7 不知火舞 法师 4 644 0.60 5
8 貂蝉 法师 3 982 0.70 4
> mutate(Data, rew使用频次 = 使用频次 / 100)
英雄 职业 熟练等级 使用频次 胜率 rew使用频次
1 后裔 射手 5 856 0.64 8.56
2 孙尚香 射手 5 211 0.10 2.11
3 狄仁杰 射手 5 324 0.20 3.24
4 李元芳 射手 4 75 0.30 0.75
5 安琪拉 法师 5 2324 0.40 23.24
6 张良 法师 4 755 0.50 7.55
7 不知火舞 法师 4 644 0.60 6.44
8 貂蝉 法师 3 982 0.70 9.82
> sqldf("
+ select
+ *, (熟练等级 + 1) as rew等级,(使用频次)/100 as rew使用频次
+ from Data
+ ")
英雄 职业 熟练等级 使用频次 胜率 rew等级 rew使用频次
1 后裔 射手 5 856 0.64 6 8.56
2 孙尚香 射手 5 211 0.10 6 2.11
3 狄仁杰 射手 5 324 0.20 6 3.24
4 李元芳 射手 4 75 0.30 5 0.75
5 安琪拉 法师 5 2324 0.40 6 23.24
6 张良 法师 4 755 0.50 5 7.55
7 不知火舞 法师 4 644 0.60 5 6.44
8 貂蝉 法师 3 982 0.70 4 9.82
> summarize(group_by(Data, 职业),
+ delay = mean(熟练等级, na.rm = TRUE))
# A tibble: 2 x 2
职业 delay
<fct> <dbl>
1 法师 4
2 射手 4.75
> str(Data)
'data.frame': 8 obs. of 5 variables:
$ 英雄 : Factor w/ 8 levels "安琪拉","不知火舞",..: 5 7 3 6 1 8 2 4
$ 职业 : Factor w/ 2 levels "法师","射手": 2 2 2 2 1 1 1 1
$ 熟练等级: num 5 5 5 4 5 4 4 3
$ 使用频次: num 856 211 324 75 2324 ...
$ 胜率 : num 0.64 0.1 0.2 0.3 0.4 0.5 0.6 0.7
> sqldf("
+ select
+ 职业, avg(熟练等级) as 等级均值
+ from Data group by 职业
+ ")
职业 等级均值
1 射手 4.75
2 法师 4.00
本文从数据筛选、数据排序、选择变量、增加变量、数据排序
五个任务角度,介绍了包dplyr
中五个核心函数,以及sql
的部分实用关键字:
功能 | 函数 | 包 | sqldf关键字 |
---|---|---|---|
筛选逻辑值 | filter() | dplyr | select、where、between |
排序 | arrange() | dplyr | desc |
选变量 | select() | dplyr | select |
创建新变量 | mutate()) | dplyr | as |
分组摘要统计 | summarize() | dplyr | group by |
最后希望可以帮助大家学习R语言。水平有限发现错误还望及时评论区指正,您的意见和批评是我不断前进的动力。