# 本代码用来计算GM(1,1)灰度模型 # 输入:x 原始数据,adv为外推预测步长 # 输出:actual 原始数据,fit 拟合数据,degree 拟合精度, # C 后验差比值,P 小概率误差,predict 外推预测值 # 主函数 GM <- function(x,adv=0) { x0 <- x k = length(x0) # AGO x1 = cumsum(x0) # construct matrix B & Y B = cbind(-0.5*(x1[-k]+x1[-1]),rep(1,times=k-1)) Y = x0[-1] # compute BtB... BtB = t(B)%*%B BtB.inv = solve(BtB) BtY = t(B)%*%Y # estimate alpha = BtB.inv%*%BtY # 建立预测模型 predict <- function(k) { y = (x0[1] - alpha[2]/alpha[1])*exp(-alpha[1]*k)+alpha[2]/alpha[1] return(y) } pre <- sapply(X=0:(k-1),FUN=predict) prediff <- c(pre[1],diff(pre)) # 计算残差 error <- round(abs(prediff-x0),digits=6) emax <- max(error) emin <- min(error) # 模型评价 incidence <- function(x) { return((emin + 0.5*emax)/(x+0.5*emax)) } degree <- mean(sapply(error,incidence)) s1 <- sqrt(sum((x0-mean(x0))^2)/5) s2 <- sqrt(sum((error-mean(error))^2)/5) C <- s2/s1 e <- abs(error-mean(error)) p <- length(e<0.6745)/length(e) result <- list(actual = x0, fit = prediff, degree = degree, C = C, P = p) # 外推预测第k+adv项 if (adv > 0) { pre.adv <- predict(k+adv-1)-predict(k+adv-2) result$predict <- pre.adv } class(result) <- 'GM1.1' return(result) } # 增加对应gm1.1类的泛型函数 print & plot print.GM1.1 <- function(mod){ cat('the result of GM(1,1)\n') cat('Actual Data:', '\n',mod$actual ,'\n') cat('Fit Data:', '\n',round(mod$fit,2) ,'\n') cat('Degree:', round(mod$degree,3) ,'\n') cat('C:', round(mod$C,3) ,'\n') cat('P:', round(mod$P,3) ,'\n') if (!is.null(mod$predict)) { cat('Predict Data:', round(mod$predict,2), '\n') } } plot.GM1.1 <- function(mod,adv=5){ prex <- numeric(adv) x <- mod$actual for (k in 1:adv){ prex[k] <- GM(x,k)$predict } value = c(x,prex) res <- data.frame(index = 1:length(value), value = value, type = factor(c(rep(1,length(x)),rep(2,length(prex))))) library(ggplot2) p <- ggplot(res,aes(x=index,y= value)) p + geom_point(aes(color=type),size=3)+ geom_path(linetype=2) + theme_bw() } # 原始数据 x = c(26.7,31.5,32.8,34.1,35.8,37.5) # 预测第7项 res <- GM(x,1) print(res) plot(res,3)
星期六, 三月 16, 2013
灰色模型的R代码
最近帮朋友写了一个灰色模型GM(1,1)的R实现,参考网上现有的matlab代码,比较容易就可以弄出来。下面是具体过程,主函数是GM(),建立的模型是一个S3类,搭配两个自定义的泛型函数print和plot可以得到结果输出和图形。
星期日, 一月 20, 2013
那些奇葩的R函数
看别人的代码会遇到一些奇葩的函数,一般的教程上很少提到,但却有很好的用处,这类函数基本上分布在base以及utils包中,下面将它们略为归纳一下,以备后用。
1,文件执行:
在用R生成一个PDF文档后,如果想去打开它,你可能会在文件夹里找到再点开。再或者我们想调用系统中的其它程序来做点事情,可能要打开cmd敲点命令。实际上这都可以在R内部完成。举例来说用pandoc转换na.md成docx再打开它。
system('pandoc d:\\rspace\\na.md -o d:\\rspace\\na.docx')
shell.exec('d:\\rspace\\na.docx')
2,网络浏览:
browseURL:浏览某个指定的网页
download.file:下载网络文件到本地
3,文件操作
dir.create:新建一个文件夹
list.dirs:显示目录下的文件夹
list.files:显示目录下的文档
file.create:文档创建
file.exists:判断文档是否存在
file.remove:文档删除
file.rename:重命名
file.append:文档添加
file.copy:文档复制
file.symlink(from, to)
file.show:显示文档内容
file.info:显示文档信息
file.edit:编辑文档
zip: 压缩文件
unzip: 解压缩文件
4,运算进度条
在一个大循环运算时,如果可以看到目前的进度是比较方便的,txtProgressBar和setTxtProgressBar函数可以帮助做到这一点,下面是内置的一个小例子:
testit <- ...="..." function="function" p="p" x="sort(runif(20)),">{
pb <- p="p" txtprogressbar="txtprogressbar"> for(i in c(0, x, 1)) {Sys.sleep(0.5); setTxtProgressBar(pb, i)}
Sys.sleep(1)
close(pb)
}
testit()
星期日, 九月 02, 2012
笨办法学R编程(6)
有时候用R来解一些Project Euler的题目会非常简单,今天就来三题连解(6、7、8)。题目就不再这里复述了,可以查看官方网站。用到函数和表达式大部分在前面都已经熟悉过了,不过还是会接触到一些新的函数。废话不多说直接上代码吧。
第六题用R的向量化计算非常简单,第七题需要用到第二题中建立的findprime函数。第八题的解决是用字符串方法,先将那一长串数字作为字符串切开,再转为数值型向量,最后用循环求乘积。为了偷懒,是直接抓取的网页,没有输入那个长长的数字。
# Euler 6 x <- 1:100 sum(x)^2 - sum(x^2) # Euler 7 n <- 0 i <- 1 m <- rep(0,10001) while (n <10001) { if (findprime(i)) { n <- n +1 m[n] <- i} i <- i + 1 } m[10001] # 预备练习,熟悉一些字符串操作函数 text <- c('hello','world','I','love','code') gsub('o',' ',text) gsub('o','*',text) gsub('o','',text) (temp1 <-paste(text,collapse=' ')) paste(text,collapse='*') paste(text,collapse='') (temp2 <- strsplit(temp1," ")) class(temp2) (temp3 <- unlist(strsplit(temp1," "))) class(temp3) # Euler 8 web <- 'http://projecteuler.net/problem=8' # 用readLines函数来抓取网页 raw <- readLines(web) raw <- raw[54:73] # 删除多余字符串 data <- gsub('<br />','',raw) # 粘合成一个字符串 num <- paste(data,collapse='') # 分割后转为数值向量 temp <- as.numeric(unlist(strsplit(num,''))) p <- numeric() for ( i in 1:(1000-4)) { p[i] <- prod(temp[i:(i+4)]) } max(p)
第六题用R的向量化计算非常简单,第七题需要用到第二题中建立的findprime函数。第八题的解决是用字符串方法,先将那一长串数字作为字符串切开,再转为数值型向量,最后用循环求乘积。为了偷懒,是直接抓取的网页,没有输入那个长长的数字。
星期六, 八月 25, 2012
笨办法学R编程(5)
星期三, 八月 22, 2012
笨办法学R编程(4)
看到各位对“笨办法系列”的东西还比较感兴趣,我也很乐意继续写下去。今天的示例将会用到数据框(data.frame)这种数据类型,并学习如何组合计算两个向量,以及如何排序。我们将用所学的东西来解决Project Euler的第四个问题,就是找出一个集合中最大的回文数。回文数是指一个像1534351这样“对称”的数,如果将这个数的数字按相反的顺序重新排列后,所得到的数和原来的数一样。开始啦!
星期一, 八月 20, 2012
笨办法学R编程(3)
星期六, 八月 18, 2012
笨办法学R编程(2)
星期五, 八月 17, 2012
笨办法学R编程(1)
在倚天屠龙记中,有一人唤作火工头陀。此人练功不靠心法,只靠模仿他人招式,由外而内,自成一家。练习编程也有如此的法门,不看文字描述,只观察和模仿别人的代码。这样也可以由外而内学会编程。《笨办法学python》的作者Zed Shaw 就说过这种笨办法入门其实更简单。阳志平在他的文章《如何学习一门新的编程语言》中也讲到,初学编程要在学习区刻意的大量练习,少看理论书。
TED上一位教育家同样谈到这么一个故事,他把一个计算机扔在一个偏远的印度小村子里不去管它,在那里没有上过学的小孩就能自己学会英语和计算机的用法。实际上人脑是非常善于自我探索和学习的。因此本系列教程的特点就是只有演示代码加少量注释。通过反复模仿和练习,揣摩代码的变化和结果,你就能自行领悟其含义,并打下坚实的编程基础。
本系列每篇文章的目的都是用R语言编程来解决一个Project Euler的问题。Project Euler是一系列由易到难的计算机编程挑战,它提供了一个平台来激发我们解决问题的灵感和思路。本人写这个教程的目的有三:一是为了好玩,二是提高编程水平,三是示范说明以提供给需要的R初学者。另外从R-Blogger上了解,已经有两位高人用R在计算Project Euler,各位也可以参照他们的文章(博客1、博客2)。
Let's Go
星期二, 三月 27, 2012
用R来进行布丰投针实验
在3月14日也就圆周率日那一天,果壳网推出一篇文章《圆周率日特献:π究竟牛B在哪里?》。其中就提到了布丰(Buffon)用投针实验来计算π的近似值。不过这篇文章并没有详细说明如何用软件来做这个实验,也看到网上有朋友在问具体的过程。所以本文尝试用R来实现这个实验,算是狗尾续貂以作消遣。另外,Maxtrix67和魏太云都对这个问题有过精彩的论述,有兴趣的朋友可以参考一下。
简单来讲,投针实验是指假设有两根平行的线,它们之间的距离是1。随意抛掷一根长度为0.5的针,那么投针便有机会与平行线相交。如果总的投掷次数为N,发生相交的次数为X,那么可以用N/X来估计π的值。具体的故事和公式还可以参考这个文章。
简单来讲,投针实验是指假设有两根平行的线,它们之间的距离是1。随意抛掷一根长度为0.5的针,那么投针便有机会与平行线相交。如果总的投掷次数为N,发生相交的次数为X,那么可以用N/X来估计π的值。具体的故事和公式还可以参考这个文章。
星期三, 三月 21, 2012
R语言编程入门之七:程序查错(完)
写程序难免会出错,有时候一个微小的错误需要花很多时间来调试程序来修正它。所以掌握必要的调试方法能避免很多的无用功。
基本的除错方法是跟踪重要变量的赋值情况。在循环或条件分支代码中加入显示函数能完成这个工作。例如cat('var',var,'\n')。在确认程序运行正常后,可以将这行代码进行注释。好的编程风格也能有效的减少出错的机会。在编写代码时先写出一个功能最为简单的部分,然后在此基础上逐步添加其它复杂的功能。对输出结果进行绘图或统计汇总也能揭示一些潜在的问题。
星期五, 三月 16, 2012
R语言编程入门之六:循环与条件
循环
for (n in x) {expr}
R中最基本的是for循环,其中n为循环变量,x通常是一个序列。n在每次循环时从x中顺序取值,代入到后面的expr语句中进行运算。下面的例子即是以for循环计算30个Fibonacci数。
x <- c(1,1)
for (i in 3:30) {
x[i] <- x[i-1]+x[i-2]
}
while (condition) {expr}
当不能确定循环次数时,我们需要用while循环语句。在condition条件为真时,执行大括号内的expr语句。下面即是以while循环来计算30个Fibonacci数。
x <- c(1,1)
i <- 3
while (i <= 30) {
x[i] <- x[i-1]+x[i-2]
i <- i +1
}
for (n in x) {expr}
R中最基本的是for循环,其中n为循环变量,x通常是一个序列。n在每次循环时从x中顺序取值,代入到后面的expr语句中进行运算。下面的例子即是以for循环计算30个Fibonacci数。
x <- c(1,1)
for (i in 3:30) {
x[i] <- x[i-1]+x[i-2]
}
while (condition) {expr}
当不能确定循环次数时,我们需要用while循环语句。在condition条件为真时,执行大括号内的expr语句。下面即是以while循环来计算30个Fibonacci数。
x <- c(1,1)
i <- 3
while (i <= 30) {
x[i] <- x[i-1]+x[i-2]
i <- i +1
}
星期三, 二月 29, 2012
R语言编程入门之五:向量化运算
星期二, 二月 28, 2012
R语言编程入门之四:字符串处理
星期一, 二月 27, 2012
R语言编程入门之三:输入与输出
如同ATM机一样,你首先得输入银行卡,才能输出得到钞票。数据分析也是如此,输入输出数据在分析工作中有重要的地位。下面对R语言中一些重要的输入输出函数进行小结,而其它的函数请参考官方指南。
1 读取键盘输入
如果只有很少的数据量,你可以直接用变量赋值输入数据。若要用交互方式则可以使用readline()函数输入单个数据,但要注意其默认输入格为字符型。scan()函数中如果不加参数则也可以用来手动输入数据。如果加上文件名则是从文件中读取数据。
2 读取表格文件
读取本地表格文件的主要函数是read.table(),其中的file参数设定了文件路径,注意路径中斜杠的正确用法(如"C:/data/sample.txt"),header参数设定是否带有表头。sep参数设定了列之间的间隔方式。该函数读取数据后将存为data.frame格式,而且所有的字符将被转为因子格式,如果你不想这么做需要记得将参数stringsAsFactors设为FALSE。与之类似的函数是read.csv()专门用来读取csv格式。
星期五, 二月 24, 2012
用R实现生命游戏(Game of Life)
生命游戏是英国数学家John Horton Conway在1970年发明的细胞自动机(cellular automaton)。它最初于1970年10月在《科学美国人》杂志中出现。生命游戏是在一个二维矩形世界中,这个世界中的每个方格居住着一个细胞。细胞的生命状态只有活着或死亡两种。细胞在下一个时刻的生死取决于相邻八个方格中活着细胞的数量。如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;相反,如果周围活细胞过少,这个细胞会因太孤单而死去。
其中一种较为丰富的设定有如下四条:
其中一种较为丰富的设定有如下四条:
- 若相邻的存活细胞数少于2,则细胞死于寂寞
- 若相邻的存活细胞数多于3,则细胞死于拥挤
- 若相邻的存活细胞数为2或3,则细胞继续存活
- 若相邻的存活细胞数正好为3,死亡的细胞得到复活
R语言编程入门之二:对象和类
R是一种基于对象(Object)的语言,所以你在R语言中接触到的每样东西都是一个对象,一串数值向量是一个对象,一个函数是一个对象,一个图形也是一个对象。基于对象的编程(OOP)就是在定义类的基础上,创建与操作对象。
对象中包含了我们需要的数据,同时对象也具有很多属性(Attribute)。其中一种重要的属性就是它的类(Class),R语言中最为基本的类包括了数值(numeric)、逻辑(logical)、字符(character)、列表(list),在此基础上构成了一些复合型的类,包括矩阵(matrix)、数组(array)、因子(factor)、数据框(dataframe)。除了这些内置的类外还有很多其它的,用户还可以自定义新的类,但所有的类都是建立在这些基本的类之上的。
对象中包含了我们需要的数据,同时对象也具有很多属性(Attribute)。其中一种重要的属性就是它的类(Class),R语言中最为基本的类包括了数值(numeric)、逻辑(logical)、字符(character)、列表(list),在此基础上构成了一些复合型的类,包括矩阵(matrix)、数组(array)、因子(factor)、数据框(dataframe)。除了这些内置的类外还有很多其它的,用户还可以自定义新的类,但所有的类都是建立在这些基本的类之上的。
星期三, 二月 22, 2012
R语言编程入门之一:导论
简单来讲,编程是借助计算机来解决某个问题。学习编程的就是训练我们解决问题的能力。有这样一种说法:在未来,不会编程的人即是文盲。
1 为什么要学习R编程
大部分情况下解决某些问题还需要依赖一些事实或数据,结合数据分析的框架和计算工具来帮助我们决策和判断。这时候R语言编程就会派上用场。例如从大的方面来看,投资方要决定在何处建立风力发电场,就需要采集天气数据加以建模分析,评估各项目方案。从小的方面来看,个人是否应该购买某个理财产品,你需要获取过去的市场信息,模拟未来可能的变化,计算该项资产未来的期望收益和标准差。所以说学习R编程就是学习在数据环境中解决问题,从中磨练技术、锻炼智力,还能得到满足的快感。
1 为什么要学习R编程
大部分情况下解决某些问题还需要依赖一些事实或数据,结合数据分析的框架和计算工具来帮助我们决策和判断。这时候R语言编程就会派上用场。例如从大的方面来看,投资方要决定在何处建立风力发电场,就需要采集天气数据加以建模分析,评估各项目方案。从小的方面来看,个人是否应该购买某个理财产品,你需要获取过去的市场信息,模拟未来可能的变化,计算该项资产未来的期望收益和标准差。所以说学习R编程就是学习在数据环境中解决问题,从中磨练技术、锻炼智力,还能得到满足的快感。
- 学会R编程,才能理解高手的代码,并从中领会其用意并成为真正的高手。
- 学会R编程,才能深入了解函数背后的理论,从而进一步解决从未有过的新问题。
星期四, 一月 05, 2012
转载:来自 Google 的 R 语言编码风格指南
本文转自Xiao Nan的博客
R语言是一门主要用于统计计算和绘图的高级编程语言. 这份 R 语言编码风格指南旨在让我们的 R 代码更容易阅读、分享和检查. 以下规则系与 Google 的 R 用户群体协同设计而成.
R语言是一门主要用于统计计算和绘图的高级编程语言. 这份 R 语言编码风格指南旨在让我们的 R 代码更容易阅读、分享和检查. 以下规则系与 Google 的 R 用户群体协同设计而成.
订阅:
博文 (Atom)