欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Getting Started with R

程序员文章站 2022-07-11 08:28:45
...

最近开始学习用R做数据分析与量化投资,于是写了一篇R语言的入门教程,希望能帮助大家快速上手。我的知乎|简书|CSDN|微信公众号PurePlay 会不定期分享量化投资与R干货, 欢迎大家关注!

1. R语言

R是一种开源的解释型脚本语言,多年来在统计学家,数据科学从业人员和学者中非常流行。 它本质上是一种函数式编程语言( functional programming language),同时支持面向对象和命令式编程范例。 R具有数以千计的附加统计和分析库可供下载,在定量金融和学术领域非常受欢迎。

R中的所有内容(包括函数)都是一个对象,可以直接传递给其他函数。

1.1 安装

1.1.1 R安装

进入官网:http://www.r-project.org/。 单击“Getting Started”部分中的下载R链接,或者单击左侧菜单中的“ CRAN”链接。 选择最接近目标计算机所在位置的适当镜像站点。 有关安装R的更多详细说明

推荐的R代码编辑器:Rstudio,VScode

1.1.2 扩展包安装和载入

R扩展包官方汇总链接:https://mirrors.tuna.tsinghua.edu.cn/CRAN/

(1)安装扩展包

  • R与Rstuidio窗口操作均可完成安装,以Rsudio为例:点击Rstudio界面右下角文件区的Packages,点击Install,在弹出对话框中 , 填入需要安装的包
  • 命令安装
# 获取R存放已经安装的包的位置,默认位置是R的安装路径下的library文件夹
.libPaths()

# 安装:扩展包名称需要加引号
# destdir:指定下载的二进制zip文件存放的位置,默认是临时会话的downloaded_packages文件夹下
# lib:指定下载的二进制zip软件包被解压后的安装位置,默认值的是.libPaths()获取的路劲
install.packages("ggplot2")
install.packages("ggplot2",
                 destdir="D:/Download/Package/R",
                 lib="D:/Program Files/R/R-3.6.1/library")

(2)载入扩展包

  • Rstudio界面:点击Rstudio界面右下角文件区的 Packages,找到你要载入的包 , 在
    前面的方框中打上勾
  • R界面:点击R界面上方的“程序包”,点击 加载程序包,在弹出的窗口中选择需要,载入的包
  • 命令载入
# 扩展包名称可以不加引号
library("ggplot2")
library("ggplot2", lib.loc="C:/Program Files/R/R3.2.2/library")

(3)量化常用扩展包

  • 数据管理:包括数据集抓取、存储、读取、时间序列、数据处理等,涉及的R包有zoo(时间序列对象)、xts(时间序列处理)、timeSeries(Rmetrics系时间序列对象)、timeDate(Rmetrics系时间序列处理)、data.table(数据处理)、quantmod(数据下载和图形可视化)、RQuantLib(QuantLib数据接口)、WindR(Wind数据接口)、RJDBC(数据库访问接口)rhadoop(Hadoop访问接口)、rhive(Hive访问接口)、rredis(Redis访问接口)、rmongodb(MongoDB访问接口)、SparkR(Spark访问接口)、fImport(Rmetrics系数据访问接口)等

  • 指标计算:包括金融市场的技术指标的各种计算方法,涉及的R包有TTR(技术指标)、TSA(时间序列计算)、urca(单位根检验)、fArma(Rmetrics系ARMA计算)、fAsianOptions(Rmetrics系亚洲期权定价)、fBasics(Rmetrics系计算工具)、fCopulae(Rmetrics系财务分析)、fExoticOptions(Rmetrics系期权计算)、fGarch(Rmetrics系Garch模型)、fNonlinear(Rmetrics系非线模型)、fOptions(Rmetrics系期权定价)、fRegression(Rmetrics系回归分析)、fUnitRoots(Rmetrics系单位根检验)等

  • 回测交易:包括金融数据建模,并验证历史数据验证模型的可靠性,涉及的R包有FinancialInstrument(金融产品)、quantstrat(策略模型和回测)、blotter(账户管理)、fTrading(Rmetrics系交易分析)等

  • 投资组合:对多策略或多模型进行管理和优化,涉及的R包有PortfolioAnalytics(组合分析和优化)、stockPortfolio(股票组合管理)、fAssets(Rmetrics系组合管理)等。

  • 风险管理:对持仓进行风险指标的计算和风险提示,涉及的R包有Performance-Analytics(风险分析)、fPortfolio(Rmetrics系组合优化)、fExtremes(Rmetrics系数据处理)

1.2 获取帮助

1.2.1 帮助文档

(1)Rstudio界面

点击Rstudio界面右下角文件区的 Help选项,在最后的搜索框中输入想了解的R包或者函数

(2)R界面

点击R界面的“帮助”,开启一个帮助网页

(3)输入命令

# 获取扩展包信息
help("readr")
? readr

# 获取函数信息
help(read_csv)
? read_csv

#搜索与关键词read_csv相关的帮助文档的信息
help.search('ggplot2')
?? ggplot2

# 获取函数ggplot的使用例子  
example("ggplot") 

# 给出有关键词ggplot的所有函数  
apropos("ggplot",mode="function")

# 打开搜索首页
RSiteSearch("") 

# 搜索有关键词ggplot的所有文档和邮件列表存档 
RSiteSearch("ggplot")
RSiteSearch("empirical")   
 
# 获取函数源代码
read_csv

# 列出当前已加载包中所含有的所有可用示例数据集
data()

1.2.2 实用网站

R的网页搜索引擎,能查找各种函数、R邮件列表归档中的讨论和博客文章:http://rseek.org

R主要的博客社区:http://www.r-bloggers.com

统计之都:http://cos.name/

Github:http://github.com/

1.3 工作空间

工作空间就是当前R的工作环境

# 获取当前工作空间
getwd()

# 设定工作空间
# 路径用双引号或者单引号,必须完整,斜杠为\\或者/
# 文件夹必须存在,如果不存在,可以用dir.create()函数先创建,但文件夹需要逐个建立。
dir.create('D:/Workfiles/Finance/Quants/R')
setwd('D:/Workfiles/Finance/Quants/R')

list.dirs("D:/Workfiles/Finance/Quants/R") #列出当前工作目录下的文件夹
list.files("D:/Workfiles/Finance/Quants/R") #列出当前工作目录下的文件
ls()  #列出当前工作空间中的对象 
rm(x) #移除(删除)一个或者多个对象 
history(num) #显示最近使用过的num个命令(默认值为25) 
savehistory(“aaa”)   #保存命令历史到当前路径下文件aaa中(默认值为.Rhistory) 
loadhistory(“aaa”)   #载入一个命令历史文件aaa(默认值为.Rhistory) 
options()  ###显示或设置当前选项 
q() #退出R或者Rstudio

1.4 R文件的输入/输出

1.4.1 保存文件

利用Rstudio/R界面保存脚本文件;保存其他文件代码如下:

# 将运行结果保存成.R或者.txt文件,相对/绝对路径均可
sink("D:/Workfiles/Finance/Quants/R/try.R")
...program
sink()

# 将工作空间里的对象(结果、变量等)保存成.Rdata
save.image('try.RData')

# 图形文件保存:可输出成pdf/png/jpeg/bmp,方法类似
pdf('xxx.pdf') 
...program
dev.off()

1.4.2 打开文件

(1)利用Rstudio/R界面
(2)输入命令

# 打开.R文件/R的脚本文件
file.edit("D:/Workfiles/Finance/Quants/R/1.4如何获得帮助.R",fileEncoding = "UTF-8") 

# 运行R脚本文件
source("xxx.R",encoding = "UTF-8")

# 打开.Rdata文件
load('try.RData')

1.5 变量

变量为我们提供了我们的程序可以操作的命名存储。 变量名称由字母(区分大小写),数字和点或下划线字符组成,不允许使用空格或特殊字符。 变量名以字母或不以数字后跟的点开头。

变量名 合法性 原因
var_name2. 有效 有字母,数字,点和下划线
VAR_NAME% 无效 有字符’%’。只有点(.)和下划线允许的。
2var_name 无效 以数字开头
.var_name, var.name 有效 可以用一个点(.),但启动点(.),不应该后跟一个数字。
.2var_name 无效 起始点后面是数字使其无效。
_var_name 无效 开头_这是无效的

可以使用向左,向右和等于运算符来为变量赋值:

# 等号赋值
var1 = c(0,1,2,3)           
# 左赋值
var2 <- c("learn","R")   
# 右赋值  
c(TRUE,1) -> var3           

在R语言中,数据类型有:数值型Numeric,整型Integer,复数型Complex,字符串Character,逻辑型Logical,原型Raw。R中的变量不必声明变量类型,R将动态地找出运行时变量的类型。

展示工作空间中的变量:

# 展示工作空间中的所有变量
ls()
# 展示工作空间中变量名包含“var”的变量
ls(pattern = "var")
# 以点(.)开头的变量默认被隐藏,设置“all.names = TRUE”参数列出
ls(all.name = TRUE)

删除变量:

# 删除指定变量
rm(var1)
# 删除所有变量
rm(list = ls())

1.6 运算符

R语言中拥有如下几种运算符类型:算术运算符,关系运算符,逻辑运算符,赋值运算符等。

1.6.1 算术运算符

下表显示了R语言支持的算术运算符。 操作符对向量的每个元素起作用。

运算符 描述
+ 两个向量相加
- 两个向量相减
* 两个向量相乘
/ 将第一个向量与第二个向量相除
%% 两个向量求余
%/% 两个向量相除求商
^ 将第二向量作为第一向量的指数

1.6.2 关系运算符

下表显示了R语言支持的关系运算符。 将第一向量的每个元素与第二向量的相应元素进行比较。 比较的结果是布尔值。

运算符 描述
> 检查第一个向量的每个元素是否大于第二向量的相应元素。
< 检查第一个向量的每个元素是否小于第二个向量的相应元素。
== 检查第一个向量的每个元素是否等于第二个向量的相应元素。
<= 检查第一个向量的每个元素是否小于或等于第二向量的相应元素。
> = 检查第一个向量的每个元素是否大于或等于第二向量的相应元素。
!= 检查第一个向量的每个元素是否不等于第二个向量的相应元素。

1.6.3 逻辑运算符

下表显示了R语言支持的逻辑运算符。 它只适用于逻辑,数字或复杂类型的向量。 所有大于1的数字被认为是逻辑值TRUE。
将第一向量的每个元素与第二向量的相应元素进行比较。 比较的结果是布尔值。

运算符 描述
& 它被称为元素逻辑AND运算符。 它将第一向量的每个元素与第二向量的相应元素组合,并且如果两个元素都为TRUE,则给出输出TRUE。
| 它被称为元素逻辑或运算符。 它将第一向量的每个元素与第二向量的相应元素组合,并且如果元素为真,则给出输出TRUE。
! 它被称为逻辑非运算符。 取得向量的每个元素,并给出相反的逻辑值。

逻辑运算符&&和|| 只考虑向量的第一个元素,给出单个元素的向量作为输出。

运算符 描述
&& 逻辑AND运算符。 取两个向量的第一个元素,并且只有两个都为TRUE时才给出TRUE。
|| 逻辑OR运算符。 取两个向量的第一个元素,如果其中一个为TRUE,则给出TRUE。

1.6.4 赋值运算符

这些运算符用于向量赋值。

运算符 描述
<−=<<− 左分配
->->> 右分配

1.6.5 其他运算符

这些运算符用于特定目的,而不是一般的数学或逻辑计算。

运算符 描述
: 冒号运算符。 它为向量按顺序创建一系列数字。
%in% 此运算符用于标识元素是否属于向量。
%*% 此运算符用于将矩阵与其转置相乘。

1.7 数据容器

数据容器data container:向量Vectors,因子Factors,列表Lists,矩阵Matrices,数据帧Data Frames,数组Arrays

1.7.1 向量Vectors

向量类似一维数组,仅保存类型相同的数据, 如果将数字与字符混合,R会将任何数值的类型转换为字符。运算符c()用于创建存储数字,字符或布尔值的向量

first_vector <- c(1,2,3,4,5,6)
second_vector <- c('a', 'b', 'c','d')
third_vector <- c('a', 1, 2, 3)
# 向量合并
new_vector <- c(first_vector,second_vector)

向量索引:

vector <- c(1,2,3,4,5,6,7,8,9)
# 获取向量第四个元素
vector[4]
# 获取第四和第八个元素
# vector[4,8]是错误的
vector[c(4,8)]
# 获取第四到第八个元素
# 第四和第八个元素都会被取出
vector[4:8]

向量化允许我们同时对所有元素执行相同的操作。

vector <- c(1,2,3,4,5,6,7,8,9)
# 向量中所有元素除以3,并保留两位小数
round(vector/3,2)

1.7.2 列表Lists

列表可以同时包含不同类型的元素,如数字、字符串、向量、列表、矩阵、函数等。

myList <- list(a = c(1,2,3,4,5),
              b = matrix(1:10, nrow = 2, ncol = 5),
              c = data.frame(price = c(89.3, 98.2, 21.2),
              stock = c("MOT", "IBM", "CSCO"))
              )

通过位置或者元素名索引:

# 返回元素列表
list1 <- myList[1]
list2 <- myList[c(1,3)]
# 返回单个元素
element1 <- myList[[1]]
element2 <- myList[["b"]]

1.7.3 矩阵Matrix

矩阵类似一维数组,只能保存类型相同的数据。

# 按列排列
mat1 <- matrix(c(1,2,3,4,5,6),
              nrow=2, ncol=3) 

# 按行排列
mat2 <- matrix(c(1,2,3,4,5,6),
              nrow=2, ncol=3, byrow=TRUE)

# 定义行名和列名
dimnames(mat2) <- list(c('one','two'),
                      c('col1','col2','col3'))

# 展示矩阵的特征
attributes(mat2)

索引方法与向量类似,需要增加一个维度

mat2[1,3]
mat2[c(1,2),3]
mat2[1:2,2:3]
mat2[,2:3]

矩阵操作也是向量化的:

# 元素服从标准正太分布的100*10矩阵
mat <- matrix(rnorm(1000),nrow=100)
# 保留三位小数,展示前9行
head(round(mat,3),9)

1.7.4 数据框Dataframe

数据框是一个混合的二维数据容器,可以包含数字,字符,布尔值和因子类型。每当从外部环境将数据读入R时,结果对象最终都可能是 一个数据帧,格式类似于一个Excel表格。

df1 <- data.frame(price = c(89.2, 23.2, 21.2),
                symbol = c('MOT','AAPL','IBM'),
                action = c('Buy','Sell','Buy'))

数据框索引[,], $

df1[1,1]
# dataframe_name $ column_name
df1$symbol

创建数据框时,字符向量将自动转换为因子,它是离散变量的向量。 为了禁止将任何字符向量转换为因子,我们可以使用stringsAsFactors = FALSE参数。

df2 <- data.frame(price = c(89.2, 23.2, 21.2),
                symbol = c('MOT','AAPL','IBM'),
                action = c('Buy','Sell','Buy'),
                stringsAsFactors = FALSE)
df1$symbol
## [1] MOT  AAPL IBM 
## Levels: AAPL IBM MOT
df2$symbol
## [1] "MOT"  "AAPL" "IBM" 
class(df1$symbol)
## [1] "factor"
class(df2$symbol)
## [1] "character"

1.7.5 环境Environment

创建环境空间,定义环境空间中的变量:

env <- new.env()
# [[]]与$均可实现环境空间中的变量定义
env[["first"]] <- 5
env[["second"]] <- 6
env$third <- 7

查看环境空间

env
# 查看环境空间中的变量名
ls(env)
# 获取环境空间中的某一变量
get("first", envir = env)

删除环境空间中的变量

rm("second", envir = env)
ls(env)

环境空间的存储特征:不按值存储对象,而是将对象位置的地址存储在内存中。 由于较大的对象不必在每次传递时都进行复制,因此可以使用更有效的代码。

env1 <- env
env1$third <- 42
get("third", envir = env)

1.8 plot()绘图

R提供了许多高级的绘图扩展包,如ggplot2, ggvis, rCharts, rgi等,此处只介绍最基本的plot()函数绘图。

x <- c(1,2,3.2,4,3,2.1,9,19)
plot(x) # 散点图
plot(x, type = "l") # 折线图

?plot # 查看更多图表类型

Getting Started with R
Getting Started with R
绘制一个有标题、横纵轴名称、基本网格的图

plot(rnorm(100), # 正太分布随机数
     main = "Some Returns", # 图标题
     cex.main = 0.9, 
     xlab = "Time",# x轴标题
     ylab = "Returns", # y轴标题
    )
# 添加基本网格
grid()
# 添加水平线与垂直线
abline(v = 40, # x = 40处绘制垂直线
      lwd = 2, # 线宽
      lty = 1, # 线型
      )
abline(h = 1, # y = 1处绘制水平线
      lwd = 3, 
      lty = 3)
# 添加额外的文本
mtext("Some text at the bottom", side = 1)
# 添加图例
legend(50, -1, "A legend")

Getting Started with R
绘制子图

# 设定2行,2列子图格式
par(mfrow = c(2, 2))
# 第一张图
plot(rnorm(100), main = "Graph 1")
# 第二张图
plot(rnorm(100), main = "Graph 2", type = "l")
# 第三张图
plot(rnorm(100), main = "Graph3", type = "s")
abline(v = 50, lwd = 4)
# 第四张图
plot(rnorm(100), type = "h", main = "Graph4")
# 重置绘图窗口
par(mfrow = c(1,1))

Getting Started with R
查看绘图所用参数

# 法一
?plot.default
# 法二
formals(plot.default)

1.9 函数

R支持命令式、函数式、面向对象编程。

1.9.1 内置函数

R语言具有大量内置函数,以下展示一些常用内置函数

# 创建标准正态分布随机数
x <- rnorm(100, mean = 0, sd = 1)
# 返回向量长度
length(x)
# 计算均值、方差、中位数
mean(x)
sd(x)
median(x)
# 计算变量值域
range(x)
# 求和/累计求和
sum(x)
cumsum(x)
# 展示前3个元素
head(x, 3)
# 获取描述统计结果
summary(x)
# 将x从大到小排序
sort(x, decreasing = TRUE)
# 计算一阶差分
diff(x)
# 以1为步长创建1至10序列
seq(1, 10, 1)
# 打印:注意两种打印的区别
cat("hello\n")
print("hello\n")
# 展示最近输入的10行命令
history(10)
# 数值计算
sqrt(2)
exp(1)
cos(1)
sin(1)
# 求函数积分
integrand <- function(x) 1/((x+1)*sqrt(x))
integrate(integrand, lower=0, upper=Inf)

1.9.2 自定义函数

自定义函数的基本语法如下

function_name <- function(arg_1, arg_2, ...) {
    Function body
    return value
}

函数的不同部分

  • 函数名称:作为具有此名称的对象存储在R环境中。
  • 参数 :当函数被调用时,需要传递具体值到参数。 参数是可选的,一个函数可能不包含参数;参数可以有默认值。
  • 函数体 :函数体包含定义函数的功能语句集合。
  • 返回值 :返回值即函数的输出。

1.10 控制结构

1.10.1 分支

x = 1
if(x) {
    print("true")
} else {
    print("false")
}

1.10.2 循环

for(i in 1:5) {
    cat(i, "\n")
}

1.11 实例:下载指定股票价格数据,计算收益率相关性

过滤无效的股票代码:

FiltSymbols <- function(symbols) {
  # 将小写字母转换为大写
  symbols <- toupper(symbols)
  # 正则表达式验证证券代码是否有效
  valid <- regexpr("^[A-Z]{2,4}$", symbols)
  #返回
  return(sort(symbols[valid == 1]))
}

symbols <- FiltSymbols(c("xom", "aapl", "cvx","ibm", "GS","600000HS" ))
cat(symbols)

下载股票价格数据:

library("quantmod")
getPrices <- function(symbols) {
  # 输入:向量类型的股票代码
  # 输出:dataframe,包含多只股票的价格数据
  for (i in 1:length(symbols)) {
    if (i != 1) {
      # 获取第i支股票的价格数据
      tempData <- getSymbols(symbols[i], src="yahoo", 
                    from="2007-01-01",to="2017-08-31",
                    auto.assign = FALSE)
      # 将收盘价合并到prices中
      prices <- cbind(prices, tempData[,4])
      cat(paste("第", i, "支股票下载完成…\r"))
    } else {
      # 获取第一支股票的价格数据
      data <- getSymbols(symbols[i], src="yahoo", 
                          from="2007-01-01",to="2017-08-31",
                          auto.assign = FALSE)
      # 仅保留收盘价
      prices <- data[,4]
      cat("第1支股票下载完成…\r")
    }
  }
  return(prices)
}

prices <- getPrices(symbols)
print(prices, max = length(symbols)*5)

计算股票收益率相关性:

showCorrelations <- function(prices) {
  # 输入:dataframe,股票价格数据
  # 输出:相关系数矩阵,两两散点图矩阵
  
  # 将股价转换为对数收益率,参数2表示对列进行计算
  returns <- apply(prices, 2, function(x) diff(log(x)))
  # 计算相关系数矩阵
  print(cor(returns, use = "complete.obs"))
  # 绘制两两散点图矩阵
  pairs(returns, main = "Pairwise Return Scatter Plot")
}
showCorrelations(prices)

Getting Started with R
欢迎关注我的知乎|简书|CSDN|微信公众号PurePlay , 会不定期分享量化金融与R干货。
Getting Started with R

相关标签: Finance with R