R编程

2018-08-31

2018-08-31
R编程浅述

1 R对象命名


  用R进行编程,书写代码时,有些特殊的字符、符号等不被系统识别。

  1)在对象命名时,不能当做对象名称的有:break/else/FALSE/for/function/if/Inf/NA/NaN/next/repeat/return/TRUE/while等。它们有特别的用法或不符合R编程规则,故不能作为对象名称。

  2)R对英文大小写字母十分敏感,因此FF和Ff视为两个不同的对象,最终运行结果也不相同。

  3)对象名称开头必须是英文字母或点号(“.”),当以点号(“.”)开头时,接续的第二个字母不能是数字。

  4)对象名称只能包含字母、数字、底线(“_“)和点号(”.“),涉及其它可能会导致错误。 `

2 R代码简化


  R的代码在使用过程中可以进行一定的简化,减少不必要的流程。举例说明,需要计算1+2+3+4+11+12+13+14+21+22+23+24+31+32+33+34的和,如下所示:

  方法一:可以在R中进行逐个输入,进行求和计算,如下所示:

 1+2+3+4+11+12+13+14+21+22+23+24+31+32+33+34
## [1] 280

  由上可知,计算得到和为280。

  方法二:使用R对编码赋值编写程序计算为例,操作如下所示:

a<-1:4
b<-11:14
c<-21:24
d<-31:34
y=sum(a)+sum(b)+sum(c)+sum(d)
y
## [1] 280

  直接运行赋值对象的编码,运行结果为280.

print(y)
## [1] 280

  通过print函数对赋值参数进行访问,运行结果为280。

(y=sum(a)+sum(b)+sum(c)+sum(d))
## [1] 280

  对表达式加括号进行运算优先,可直接运行括号内的结果为280。

sum(a,b,c,d)
## [1] 280

  对整体赋值的表达式直接进行求和,结果为280。当然,也可用分号,将短句进行连接,直接一行展示运行,如下所示:

a<-1:4;b<-11:14;c<-21:24;d<-31:34;sum(a,b,c,d)
## [1] 280

  通过“;”将短代码进行连接,减少代码布局的空间,得到结果为280。

2.1 R的条件控制语句

  1)if/else

  如果假定一个条件是5,只要其中一个数的值在该范围内,就会显示一个结果,如下所示:

 X<-5
 if(X<6) "运行"
## [1] "运行"

  由上可知,当第一个条件X满足X<6时,5明显小于6,执行后就会显示出结果“运行”。

X<-4
if(X>4) print(3*4)  else   print(5*4)
## [1] 20

  由上可知,当X大于4时,执行3和4相乘;当X不大于4时,执行5和4相乘,得到结果5乘以4为20。

  2)ifelse语句

X<-1
ifelse(X>2,2*X,3*X)
## [1] 3

  由上可知,当X大于2时,执行2和X相乘;否则,执行3与X相乘。而赋值X=1,明显小于2,选择1和3相乘,得到结果为3。

  3)switch语句

switch(1,2*3,sd(1:5),runif(3))#返回(2*3,sd(1:5),runif(3))list中的第一个成分。
## [1] 6

  由以上显示,返回(2*3,sd(1:5),runif(3))list中的第一个成分为6。

2.2 R的循环语句

  1)for循环

  例如,计算1+2+3+4+5+…+200的值:

s<-0#s初始值的和为0
for(i in 1:200){#循环变量i从1到200
s<-s+i #每次循环在和的基础上加i
}
print(s)# 当i从1取值到200后,循环终止,得出最后结果。
## [1] 20100

  由上可知,当i从1取值到200后,循环终止,得出最后结果为20100。

  2)while结构

  例如,计算1+2+3+4+5+…+200的值:

s<-0#s初始值为0
i<-1#循环变量初始值为1
while(i<=200){#当i小于等于200时,进行循环
s<-s+i#在每次循环结果上加i
i<-i+1#循环变量值在不停的变化
}
print(s)#当循环变量值i为201时,得出计算结果
## [1] 20100

  由上可知,当循环变量值i为201时,得出计算结果为20100。

  3)repeat结构

  例如,计算1+2+3+4+5+…+200的值:

s<-0#s初始值为0
i<-1#循环变量初始值为1
repeat{#进入循环
if(i<=200)#当i小于等于200时,进行求和
{
s<-s+i#在每次循环结果上加i
i<-i+1
} 
else break#循环变量值在不停的变化

} # 当大于200时,进行终止
print(s)#当循环变量值i为201时,得出计算结果
## [1] 20100

  由上可知,当循环变量值i为201时,得出计算结果为20100。

3 自定义函数


  自定义函数创建需要用到function,函数规则为:

  sapply(X,FUN,options)

  其中,X:数据框或矩阵;FUN:为任意的函数;options:若被指定,则将被传递给FUN。操作如下所示:

library(readxl)   # 读取前加载包
## Warning: package 'readxl' was built under R version 3.4.4
data=read_excel("D:/TASK/4 净水器数据.xlsx")
X=data[,2:3]  # 样本数据
Des.Fun=function(X,...){
Av=mean(X,na.rm=TRUE)  # 均值
Sd=sd(X,na.rm=TRUE)  # 标准差
n=length(X)  # 样本数量
Sk=sum((X-Av)^3/Sd^3)/n  # 偏态
Ku=sum((X-Av)^4/Sd^4)/n-3  # 峰度系数
result=list(av=Av,sd=Sd,skew=Sk,kurt=Ku) # 均值、标准差、偏态和峰度系数作为列表数值
return(result)
}
DesRep=sapply(data[,2:3],FUN=Des.Fun,na.rm=T)
DesRep
##      原价     促销价  
## av   3539.72  2510.84 
## sd   3693.031 2938.372
## skew 3.623989 3.772969
## kurt 20.94813 23.07247

  由上可知,通过自定义函数计算,得出均值、标准差、偏态和峰度系数作为列表数值。

4 R代码调试


  R使用过程中,有时程序无法运行,R通常会给出报错信息,根据报错的信息找出错误的原因,也可以通过traceback()、Debug()和Browser()函数找出程序出错的地方。为了进一步提高R的程序代码运行时间,可对代码语言程序进行调试。如下所示:

  第一次调试,结果如下显示:

tst<-proc.time()  # 将proc.time()值保存在tst中
tx<-rnorm(10000)  # 产生10000个服从正态分布的随机数保存在对象tx
td<-rnorm(10000)  # 产生10000个服从正态分布的随机数保存在对象td
xd<-c()  
for (i in 1:10000){
  xd<-c(xd,tx[i]+td[i])
} # 计算i在1到10000时,tx和td的和
proc.time()-tst  # 运行程序调试结果
##    user  system elapsed 
##    0.56    0.05    0.61

  由上述知,user是用户,system 是指系统,elapsed是指程序运行时长。在运行基础上,继续进行第二次调试,如下所示:

tst<-proc.time()  # 将proc.time()值保存在tst中
xd<-rep(NA,10000) 
for (i in 1:10000){
  xd<-c(xd,tx[i]+td[i]) # 计算i在1到10000时,tx和td的和
}
proc.time()-tst  # 运行程序调试结果
##    user  system elapsed 
##    1.75    0.00    1.79

  由上可知,通过对比第一次和第二次的调试结果,发现程序运行时间在逐渐减少。进行第三次调试,结果如下显示:

tst<-proc.time()  # 将proc.time()值保存在tst中
xd<-tx+td # 计算tx和td的和
proc.time()-tst  # 运行程序调试结果
##    user  system elapsed 
##       0       0       0

  由上可知,通过第三次调试,明显可以看出,第三次的调试在性能上总体比前2次效果好,在一定条件下选择第三种效果较好。

5 参考文献

  [1]方匡南, 朱建平, 姜叶飞. R数据分析:方法与案例详解[M]. 电子工业出版社, 2015.

  [2]洪锦魁, 蔡桂宏. R语言:迈向大数据之路[M]. 清华大学出版社, 2016.

  [3]薛薇. 基于R的统计分析与数据挖掘[M]. 中国人民大学出版社, 2014.