标签:
R语言编程艺术,第一章:快速入门
1.生成n个基于N(0,1)分布的随机数rnorm(n)
取绝对值abs(),
取平均值mean(),
取标准差sd()
2.使用批处理命令:把下列命令保存在z.R的文件中
pdf(“xh.pdf”) #保存为pdf格式的图形文件并命名为xh.pdf
hist(rnorm(100)) #调用hist函数生成直方图
dev.off() #关闭图形设备,即把生成的图形文件存盘
如何调用呢?
R CMD BATCH z.R
3.创建一个向量:
x <- c(1,2,4) #c是连接的意思
q <- c(x,x,8) #可以创建包括向量的向量 q为 1 2 4 1 2 4 8
4.元素的索引: R是从1开始索引的
x[3]表示的时索引向量中的第三个元素
索引片段:x[2:3]
可以把这些索引值存储在片段中,使用赋值符号<-使用注释是一个好的习惯,在R中的交互式命令中也可以使用,因为查看历史命令可以帮助你回忆当时是怎么思考的
5.R会内置一部分数据集,使用data()查看
6.q()退出,注意在大型的数据集中,最好保存历史会话
二 函数入门
1.计算向量中余数的个数
oddcount <- function(x){
k <- 0 # 给计数器赋初值
for(n in x){
if(n %% 2 == 1) k <- k+1 # R的取余为 %%
}
return (k)
}
2.在函数内部使用的变量都是局部变量,他们在函数返回值之后就撤消了
全局变量则是在函数之外创建的变量,在函数内部也可以访问:
f <- function(x) return(x+y) #定义函数
y <- 3
f(5)的结果是 8
3.关于函数调用,赋值的问题,先给定一个函数:
f <- function(x=1,y,z) return(x+y+z)
虽然函数缺省x的值,但是调用时还要小心
f(2,3) #函数将把2重新赋给x,把3赋给y,z没有值,错误
f(y=2,z=3) #指明变量的值,正确
f(2,2,3) #函数将重新把x的值赋为2,然后y是2,z是3
4.列表list
创建一个列表吧
x <- list(u=2,v="abc")
索引列表中的值用$
x$u
5.矩阵
如何创建矩阵?
行绑定:rbind() 即按行绑定:
m <- rbind(c(1,4),c(2,2))
> m
[,1] [,2]
[1,] 1 4
[2,] 2 2
列绑定:cbind() 按列绑定:
n <- cbind(c(1,4),c(2,2))
> n
[,1] [,2]
[1,] 1 2
[2,] 4 2
6.混合型的数据矩阵称为数据框
d <- data.frame(list(kids=c("Jack","Jill"),ages=c(12,10)))
> d
kids ages
1 Jack 12
2 Jill 10
1.添加或删除向量元素
实际上就是重新对变量赋值
x <- c(1,2,3,5)
x <- c(x[1:3],4,x[4]) #我想添加一个向量元素4使之变成(1,2,3,4,5)
x <- c(x[1:3]) #我想删除一个向量元素5使之变成(1,2,3)
2.关于循环的再认识
循环的目的是什么?是遍历向量中各个元素的值?还是不仅要求值还想要取得该元素的序列?
如果只要求使用元素的值,使用下列的写法:
for(n in x){
statement }
如果不单单要求值,还要取得元素的索引号,使用下面的写法:
for (i in 1:length(x)){
statement } #这里的x[i]与上面的n相同,代表向量中各个元素的可能取值
3.遍历取值的时候,应避免向量元素个数小于1
正常情况下是这样的:
x <- c(1,2,3)
> 1:length(x)
[1] 1 2 3
如果是这样:
x <- c()
> 1:length(x)
[1] 1 0 #这明显不是我们想要的结果
4.矩阵在内存序列中是如何储存的?
是按列存储的,不论是如何生成矩阵的,是按列绑定cbind,还是按行绑定rbind,在内存序列中
都是按列存储的
如何验证?
m <- rbind(c(1,2),c(3,4)) #这里的矩阵m是按行绑定生成的
> m
[,1] [,2]
[1,] 1 2
[2,] 3 4
> m + 10:13
[,1] [,2]
[1,] 11 14
[2,] 14 17
显然,矩阵m按列存储为一个四元向量(1,3,2,4),加上(10,11,12,13)得到(11,14,14,17)
5.同多数脚本语言一样,R不需要事先声明变量,注意这里的"不需要"只是其中的一种方法.
创建向量的另一种方法:(声明变量法)
y <- vector(length=2) #为变量y分配两个存储空间,没有赋值的情况下,两个都是FALSE
y[1] <- 5 #一旦对其中任何一个元素赋值,其它元素自动置为0,此时y[2]为0
y[2] <- 12 #生成一个(5,12)的二元向量
说明一下为什么需要上述的方法:如果在循环体中每次使用类似于y <- c(5,12)的赋值,会
减慢代码的运行速度,因此使用上述方法在一开始就分配内存空间,而进入循环体后只是填充
空间.
另一种方法就是常见的
y <- c(5,12)
6.循环补齐
(1)向量与向量相加
如果长度不相等,短的就会自动与长的补齐,
注意,这里不是补零!而是循环补
c(1,2,3)
c(1,2,3,1,2) #补成5位的
c(1,2,3,1,2,3,1) #补成7位的
(2)向量与矩阵相加
注意,因为矩阵无法循环补齐,故只能是短向量与长矩阵相加时,会出现短向量循环补齐
(3)矩阵与矩阵相加
只能是相同行和列的矩阵相加,不存在补齐的情况!
7.索引不连续的向量
x <- c(1,5,2,0,5,6,7,8)
> x[c(1,3,4)] #索引x向量的第一位,第三位和第四位元素
[1] 1 2 0
> x[1:3] #索引连续元素的方法:x向量的前三个元素
[1] 1 5 2
> x[c(1,1)] #重复索引第一位的元素
[1] 1 1
以上都是对R说我想要某某元素,还有一种方法是:我不想要某某元素,其它的都要:
> x[c(-1)] #除了第一位元素,其它都要
[1] 5 2 0 5 6 7 8
> x[c(-3:-5)] #除了第三到第五位元素,其它都要
[1] 1 5 6 7 8
8.创建向量
回忆下我们目前知道的创建向量的方法:
x <- c(1,2,3,4,5,7,5,9)
如果想创建连续值得向量(注意他们的步进都是1):
x <- 1:8 #正向
x <- 5:-2 #负向
想改变步进的大小?没问题,使用seq()函数:
x <- seq(from=12,to=29,by=3)
> x #注意这里终止于27,而不是29,因为它们之间的间隔小于步进3
[1] 12 15 18 21 24 27 #上述函数可以理解为生成开始于12,步进为3,最大不超过29的序列
同样生成负向的序列:
> seq(from=0.8,to=-0.1,length=10) #这里规定了向量的总长度,自动计算步进
[1] 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0 -0.1
seq()的另一个作用:
seq(x)与1:length(x)的作用相同,甚至更优,因为对于空值x
x <- c()
> 1:length(x)
[1] 1 0 #这明显不是我们想要的结果
> seq(x)
integer(0) #该结果会是上面循环迭代0次,符合我们的期望
创建重复序列的向量:rep(x,times)
> rep(c(1,3,8),4)
[1] 1 3 8 1 3 8 1 3 8 1 3 8
> rep(c(1,3,8),each=4) #每个元素重复4遍
[1] 1 1 1 1 3 3 3 3 8 8 8 8
9.布尔值求解any(),all()
x <- 1:9
> any(x>5) #x中有>5的元素吗?
[1] TRUE
> all(x>5) #x中所有元素都>5吗?
[1] FALSE
实例一:寻找连续出现1的游程
x <- c(1,0,0,1,1,1,0,1,1)
#version 1.0 findruns <- function(x,k){ #k是指连续出现1的个数 n <- length(x) runs <- NULL for (i in 1:(n-k+1)){ #为什么不是1:n?因为要保证连续的k个数比较 if(all(x[i:(i+k-1)]==1)) #这个判断值真的是太绝妙了! runs <- c(runs,i) #重复赋值,可能会拖慢代码的运行速度 } return(runs) }
#version 2.0 findruns <- function(x,k){ n <- length(x) runs <- vector(length=n) #不同于上个版本的地方,先声明runs的变量 count <- 0 #为runs分配的空间是用不完的,count计算用了多少位 for (i in 1:(n-k+1)){ if (all(x[i:(i+k-1)]==1)){ count <- count + 1 runs[count] <- i #这里count也充当runs的序列索引号 } } if (count > 0){ runs <- runs[1:count] #释放未利用的内存空间 } else runs <- NULL return (runs) }
实例二:预测离散值时间序列
preda <- function(x,y){ n <- length(x) k2 <- k/2 #如果在连续k天内1的数量>= k/2 pred <- vector(length=n-k) for (i in 1:(n-k)) { if (sum(x[i:(i+k-1)]) >= k2) #如果在连续k天内1的数量>= k/2 pred[i] <- 1 #那么预测下一个值为1 else pred[i] <- 0 } return(mean(abs(pred-x[(k+1):n]))) }
但在实际中很少用诸如
sum(x[i:(i+k-1)])计算连续k个元素之和,因为重复计算,这会拖慢代码速度
我们可以使用cumsum()函数代替:cumsum是计算向量的累积和
y <- c(5,2,-3,8)
> cumsum(y)
[1] 5 7 4 12
比如我想计算第二个到第四个数的和
x <- cumsum(y)
x[4] - x[1]
那第一个到第三个数之和呢? 为了统一形式:
x[3] - x[0] 但R中向量元素是从零开始索引的,为了形式上的统一
我们使用如下办法:
csx <- c(0,cumsum(y))
这样以来我们就可以写成
csx[4] - scx[1] 来表示向量元素中第一个数到第三个数之和
基于此,我们更改第一个版本的代码:
preda <- function(x,y){ n <- length(x) k2 <- k/2 #如果在连续k天内1的数量>= k/2 pred <- vector(length=n-k) csx <- c(0,cumsum(x)) #新添的代码! for (i in 1:(n-k)) { if (csx[i+k] - csx[i] >= k2) #如果令i=1,k=3,该语句即为csx[4] - csx[1] #来表示向量元素中第一个数到第三个数之和 pred[i] <- 1 #那么预测下一个值为1 else pred[i] <- 0 } return(mean(abs(pred-x[(k+1):n]))) }
标签:
原文地址:http://www.cnblogs.com/bigpo/p/4246575.html