R 编程实用技巧

数据处理进阶 | 爬虫 | 数据库

Posted by Paradise on January 28, 2021

善用 apply 函数族

R 语言的运行性能较差,使用 apply 函数可以避免使用大量的 for 循环,有效提高代码运行速度。尤其是处理较大的数据集的时候。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# apply 函数作用于向量
x <- cbind(3, c(1:5, 4:1))
apply(x, MARGIN=2, FUN=mean)

x <- array(c(1:24), dim=c(2,3,4))
apply(x, MARGIN=3, FUN=sum)

# 使用自定义的函数
odd_num <- function(x){
	return (x %% 2 == 1)
}
bool <- apply(data.frame(1:10), MARGIN=1, FUN=odd_num)
# 注意 apply 只能用于 data.frame, array, tibble 等向量类型

# 使用 lapply 对列表进行循环
x <- list(a1=c(1:8), a2=c(T, T, F, F, F, T))
lapply(x, mean)		# 存在强制转换过程
lapply(x, quantile)

# lapply 返回列表,而 sapply 返回矩阵
sapply(x, mean)

# tapply 提供更强大、更灵活的循环方式
x <- as.factor(c(1,1,2,3,3))
tapply(x, x, length)

基本数据转换

1
2
3
4
5
6
as.character(c(1:3))
as.complex(c(1:3))
as.numeric(c('1', '2', '3'))
as.double(c('1', '2', '3'))
as.integer(c(1.1, 1.5, 1.9))
as.logical(c(-1, 0, 1))

使用 source 命令

1
2
3
4
5
path <- 'C:/Users/Paradise/Desktop/RWorkspace'
setwd(path)
list.dirs()
list.files()
source('testCode.R')

创建自定义的闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
# 使用 R 的闭包可以产生类似与 Java 和 Python 中的类对象的使用效果
exmp <- function(){
    fun1 <- function(){
        return ("I'm fun1, hahaha!!!")
    }
	fun2 <- function(){
        return ("I'm fun2, hehehe...")
    }
    list(fun1=fun1, fun2=fun2)
}
test <- exmp()
test$fun1()
test$fun2()

使用 R 爬取网络数据

1
2
3
4
5
6
7
8
9
10
11
library(xml2)
library(rvest)

# 读取html文档
html_text <- read_html('test.html')
View(html_text)

# 读取url源码
url <- 'http://s.askci.com/stock/a/?reportTime=2017-12-31&pageNum=1'
web <- read_html(url, encoding='utf-8')
View(web)

获取源码后可以使用 View 在 RStudio 的编辑器中打开 HTML 文档的树状图,这时点击对应元素节点最右边的小图标,可以将对应的解析代码发送到 Console(如下图)。这一点非常方便好用,因为 R 自动将 HTML 文档解析为可以操作的数据类型,而不需要手动写代码去解析。这里有点像 Python 的 BeautifulSoup,但是通过 RStudio 可以直接在图形界面傻瓜式操作

html-tree

console

使用 R 连接 MySQL 服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
library(DBI)
library(RMySQL)

# 创建 connection
create_conn <- function(pw, db){
	conn <- dbConnect(
        MySQL(), host='localhost', user='root', password=pw, dbname=db
    )
    return (conn)
}
conn <- create_conn('******', '******')

# 获取 database 相关信息和 tables 列表
summary(conn)
dbGetInfo(conn)
dbListTables(conn)

# 使用sql语句进行设置
local_infile <- dbSendQuery(conn,"SHOW VARIABLES LIKE 'local_infile';")
# 将该变量设置为 TRUE,允许 RMySQL 远程写入数据
dbSendQuery(conn, 'SET GLOBAL local_infile=1;')
# 避免读取的中文内容出现乱码
dbSendQuery(conn, "SET NAMES gbk")
# 用于查看数据库储存位置
sql <- "SHOW GLOBAL VARIABLES LIKE '%datadir%';"

# 读写 tables 快捷方式
stock_info <- dbReadTable(conn=conn, 'tbName')
dbWriteTable(conn, "data", data, overwrite=TRUE)

# 使用 sql 语句查询
dbGetQuery(conn, 'select * from tbName;')
resp <- dbSendQuery(conn, 'select * from tbName limit 5')
dbFetch(resp)
dbClearResult(resp)

# 关闭连接
dbDisconnect(conn)

利用 R 内置的数据集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 查看包内数据集
data(package='ISLR')
# 查看所有包的数据集
data(package=.packages(all.available = TRUE))

# 自带的基本数据集
"--------------------------------- 向量 ------------------------------------"
# euro--欧元汇率,长度为11,每个元素都有命名
# landmasses--48个陆地的面积,每个都有命名
# precIp--长度为70的命名向量
# rivers--北美141条河流长度
# state. abb--美国50个州的双字母缩写
# state area--美国50个州的面积
# state name--美国50个州的全称
"--------------------------------- 因子 -----------------------------------"
# state.division--美国50个州的分类,9个类别
# state.region--美国50个州的地理分类
"------------------------------- 矩阵,数组 --------------------------------"
# euro.cross--11种货币的汇率矩阵
# freeny.x--每个季度影响收入四个因素的记录
# state.x77--美国50个州的八个指标
# USPersonalExpenditure--5个年份在5个消费方向的数据
# VADeaths--1940年弗吉尼亚州死亡率(每千人)
# volcano--某火山区的地理信息(10米×10米的网格)
# WorldPhones--8个区域在7个年份的电话总数
# iris3--3种鸢尾花形态数据
# Titanic--泰坦尼克乘员统计
# UCBAdmissions--伯克利分校1973年院系、录取和性别的频数
# crimtab--3000个男性罪犯左手中指长度和身高关系
# HairEyeColor--592人头发颜色、眼睛颜色和性别的频数
# occupationalStatus--英国男性父子职业联系
"-------------------------------- 类矩阵 ----------------------------------"
# eurodist--欧洲12个城市的距离矩阵,只有下三角部分
# Harman23.cor--305个女孩八个形态指标的相关系数矩阵
# Harman74.cor--145个儿童24个心理指标的相关系数矩阵
"-------------------------------- 数据框 ----------------------------------"
# airquality--纽约1973年5-9月每日空气质量
# anscombe--四组x-y数据,虽有相似的统计量,但实际数据差别较大
# attenu--多个观测站对加利福尼亚23次地震的观测数据
# attitude--30个部门在七个方面的调查结果,调查结果是同一部门35个职员赞成的百分比
# beaver1--一只海狸每10分钟的体温数据,共114条数据
# beaver2--另一只海狸每10分钟的体温数据,共100条数据
# BOD--随水质的提高,生化反应对氧的需求(mg/l)随时间(天)的变化
# cars--1920年代汽车速度对刹车距离的影响
# chickwts--不同饮食种类对小鸡生长速度的影响
# esoph--法国的一个食管癌病例对照研究
# faithful--一个间歇泉的爆发时间和持续时间
# Formaldehyde--两种方法测定甲醛浓度时分光光度计的读数
# Freeny#--季度收入和其他四因素的记录
# datingfrom#配对的病例对照数据,用于条件logisti回归
# InsectSprays--使用不同杀虫剂时昆虫数目
# iris--3种鸢尾花形态数据
# LifeCycleSavings--50个国家的存款率
# longley--强共线性的宏观经济数据
# morley--光速测量试验数据
# mtcars--32辆汽车在11个指标上的数据
# OrchardSprays--使用拉丁方设计研究不同喷雾剂对蜜蜂的影响
# PlantGrowth--三种处理方式对植物产量的影响
# pressure--温度和气压
# Puromycin--两种细胞中辅因子浓度对酶促反应的影响
# quakes--1000次地震观测数据(震级>4)
# randu--在VMS1.5中使用FORTRAN中的RANDU三个一组生成随机数字,共400组
# rock--48块石头的形态数据
# sleep--两药物的催眠效果
# stackloss--化工厂将氨转为硝酸的数据
# swiss--瑞士生育率和社会经济指标
# ToothGrowth--VC剂量和摄入方式对豚鼠牙齿的影响
# trees--树木形态指标
# USArrests--美国50个州的四个犯罪率指标
# USJudgeRatings--43名律师的12个评价指标
# warpbreaks--织布机异常数据
# women--15名女性的身高和体重
"------------------------------- 类数据框 ---------------------------------"
# ChickWeight--饮食对鸡生长的影响
# CO2--耐寒植物CO2摄取的差异
# DNase--若干次试验中, DNase浓度和光密度的关系
# Indometh--某药物的药物动力学数据
# Loblolly--火炬松的高度、年龄和种源
# Orange--桔子树生长数据
# Theoph--茶碱药动学数据
"--------------------------------- 列表 -----------------------------------"
# state.center--美国50个州中心的经度和纬度
"------------------------------- 时间序列 ---------------------------------"
# airmiles--美国1937-1960年客运里程营收(实际售岀机位乘以飞行哩数)
# AirPassengers--BoX&Jenkins航空公司1949-1960年每月国际航线乘客数
# austres--澳大利亚1971-1994每季度人口数(以千为单位)
# BJsales--有关销售的一个时间序列
# BJsales.lead--前一指标的先行指标(leading indicator)
# C02--1959-1997年每月大气CO2浓度(ppm)
# discoveries--1860-1959年每年巨大发现或发明的个数
# Deaths--1974-1979年英国每月支气管炎、肺气肿和哮喘的死亡率
# fdeaths--前述死亡率的女性部分
# mdeaths--前述死亡率的男性部分
# freeny.y--每季度收入
# JohnsonJohnson--1960-1980年每季度Johnson&Johnson股票的红利
# LakeHuron--1875-1972年某一湖泊水位的记录
# lh--黄体生成素水平,10分钟测量一次
# lynx--1982-1934年加拿大猞猁数据
# nhtemp--1912-1971年每年平均温度
# Nile--1871-1970尼罗河流量
# nottem--19201939每月大气温度
# presidents--1945-1974年每季度美国总统支持率
# UKDriverDeaths--1969-1984年每月英国司机死亡或严重伤害的数目

END