创建函数

本文通过创建体重指数(BMI)函数,介绍如何利用R编程处理数据。以BMI为例,展示如何为函数设置默认参数及错误处理。还讨论了length()函数、stop()函数在错误处理中的应用,并对比了paste()和cat()函数的差异。同时,利用switch()函数改进了处理多个个体BMI的函数,探讨了如何处理向量输入的情况。
摘要由CSDN通过智能技术生成

以创建体重函数为例:BMI=Weight/Height^2

> BMI<-function(Weight,Height){
+     bmi<-Weight/Height^2
+     names(bmi)<-"BMI"
+     return(bmi)
+ }

了给该列表的各个元素命名,你可以使用如下的代码:

> BMI<-function(weight,height){
+     bmi<-weight/height^2
+     res<-list(Weight=weight,Height=height,BMI=bmi)
+     return(res)
+ }
> BMI(60,1.62)
$Weight
[1] 60

$Height
[1] 1.62

$BMI
[1] 22.86237

现在假设我们想要计算多个个体的BMI。比如John和peter的:

> john<-c(74,1.90)
> peter<-c(70,1.82)
> mydata<-rbind(john,peter)
> for(i in 1:2){
+     print(BMI(mydata[i,1],mydata[i,2]))
+ }
$Weight
john 
  74 

$Height
john 
 1.9 

$BMI
    john 
20.49861 

$Weight
peter 
   70 

$Height
peter 
 1.82 

$BMI
   peter 
21.13271 

接下来这段代码用一个实例来说明具有默认值的参变量以及能处理一些错误的函数stop()的用法。

> BMI<-function(weight,height,height.unit="m"){
+     if(length(weight) !=length(height)) 
+         stop("the vectors weight and height must have the same length.")
+     if(height.unit == "cm")height<-height/100
+     bmi<-weight/height^2
+     res<-list(Weight=weight,Height=height,BMI=bmi)
+     return(res)
+ }
> BMI(70,1.82)
$Weight
[1] 70

$Height
[1] 1.82

$BMI
[1] 21.13271

补充函数用法:(1)length函数:length(x),表示一个向量的长度。

(2)stop()函数:停止运行下一步。

当然,使用函数stop()肯会带来一些苦恼,例如,在一项模拟研究中,人们常需要反复地调用某个函数。如果在某一次调用中

该函数返回了一个错误,则整个模拟就会停止。明智的做法是使用函数try():如果函数遇到了一个错误,相关的错误信息将会被储存在一个对象中但不会停止模拟的运行。

>set.seed(123) 
#set.seed()用于设定随机数种子,一个特定的种子可以产
#生一个特定的伪随机序列,这个函数的主要目的,是让你的模拟能够可重复出现,
#因为很多时候我们需要取随机数,但这段代码再跑一次的时候,结果就不一样了
#,如果需要重复出现同样的模拟结果的话,就可以用set.seed()。在这里我们就
#是让下面的结果可以重复出现123次,而不是每次的值都不一样
>x<-rnorm(50) 
 #rnorm(n, mean = 0, sd = 1)产生n个服从正态分布的随机数
>doit<-function(x){
    x<-sample(x,replace=TRUE)     
#sample(x, size, replace = FALSE, prob = NULL) sample是随机抽样函数,
#x表示进行随机抽样的对象,size表示抽样的样本数,replace=T表示放回抽样,即可
#重复抽样。
        if(length(unique(x))>30) mean(x)
        else{stop("too few unique points")}
}
res<-lapply(1:100,function(i) try(doit(x),TRUE))
#lapply(X, FUN, ...)
#lapply函数
#可以循环处理列表中的每一个元素
#lapply(参数):lapply(列表,函数/函数名,其他参数)
#总是返回一个列表

根据个体的BMI值就可以将他们划分为不同的体重类别或等级,BMI与体重类别之间的对应关系如下表所示:

bmi与体重类别之间的对应关系
严重体重过轻体重过轻正常体重

中度肥胖严重肥胖病态肥胖
【15,16.5)[16.5,18.5)【18.5,25)【25,30)【30,35)【35,40)

【40,41)

 

 

 

 

 

 

 

 

下面的函数将根据用户的BMI值输出他们的体重类别。

>BMI<-function(Weight,Height){
+     bmi<-Weight/Height^2
+     names(bmi)<-"BMI"
+     return(bmi)
+ }
>weight.category<-function(bmi){
        if(bmi<16.5) category<-"severely underweight"
        else{
            if(bmi<18.5) category<-"underweight"
            else{
                 if(bmi<25) category<-"normal weight"
                 else{
                      if(bmi<30) category<-"overweight"
                      else{
                           if(bmi<35) category<-"moderate obesity"
                           else{
                                if(bmi<40) category<-"severe obesity"
                                else{
                                     if(bmi<41) category<-"morbid obesity"}}}}}}
        cat(paste("your BMI is: ",category,".\n",sep=""))}

#cat( ... , file = "", sep = " ", fill = FALSE, labels = NULL,append = FALSE)
#file:一个文件链接或文件名,若不写则表示输出到控制台;
#sep:分隔符
#append:是否追加,当且晋档参数file是文件名而非链接时,此参数才有效
————————————————

补充:paste(),cat()函数的区别

从下面的例子中可以清晰的了解cat函数与paste函数的区别.

> paste(1:9,c("st","nd","rd",rep("th",6)),sep="",collapse=",")
[1] "1st,2nd,3rd,4th,5th,6th,7th,8th,9th"
> cat(1:9,c("st","nd","rd",rep("th",6)),sep="")
123456789stndrdthththththth

函数weight.category()的代码可以用函数switch()来简化。

>BMI<-function(Weight,Height){
+     bmi<-Weight/Height^2
+     names(bmi)<-"BMI"
+     return(bmi)
+ }
>weight.category<-function(bmi){
        intervals.BMI<-c(15,16.5,18.5,25,30,35,40,41)
        code<-as.character(rank(c(bmi,intervals.BMI),
ties.method="max")[1])

        category<-switch(code,"2"="severely underweight",
"3"="underweight" "4"="normal weight","5"="overweight",
"6"="moderate obesity","7"="severely obesity","8"="morbid obesity")
 cat(paste("your BMI is:",round(bmi,3),"this corresponds to weight category:",category,sep=""))
        
}
weight.category(BMI(70,1.82)$BMI)
your BMI is:21.133.
 this corresponds to weight category:normal weight.


##rank(x, na.last = TRUE,
     ties.method = c("average", "first", "random", "max", "min"))
#(1) rank 函数是对一维度数组、向量x 进行排序。若x 为数值,则按照小数在线大数在后的原则进行排序,#若x 为因子,则应参考[说明1]进行顺序因子设计。
#P.S. 实际情况中,存在大量用二维表格描述的数据,比如行表示地点列表示时间的统计表,若进行排序,应##先通过字符拼接的手段将表格转化为一维的向量,否则结果将失去意义。
#(2) rank 将数据分为确定值与缺失值两种。缺失值可按先后排在确定值之间(na.last = FALSE), 也可排在#之后(na.last = TRUE), 也可保留,不参与排序(na.last = "keep").
#(3) "first" 是最基本的排序,小数在前大数在后,相同元素先者在前后者在后。
  "max" 是相同元素都取该组中最好的水平,即通常所讲的并列排序。
  "min" 是相同元素都取该组中最差的水平,可以增大序列的等级差异。
  "average" 是相同元素都取该组中的平均水平,该水平可能是个小数。
  "random" 是相同元素随机编排次序,避免了“先到先得”,“权重”优于“先后顺序”的机制增大了随机的程度。


##
#switch(expr, list)
#其中,expr为表达式,其值或为一个整数值或为一个字符串;list为一个列表。
#运行机理:若expr的计算结果为整数,且值在1~length(list)之间时,则switch()函数返回列表相应位置的#值。若expr的值超出范围,则没有返回值(老版本的R中返回NULL)。
#ex:
> x<-2
> switch(x,"yangfan","obama","trump")
[1] "obama"

可是,当这个函数用于一个向量时会输出一个错误的结果

> weight.category(BMI(c(70,74),c(1.82,1.90))$BMI)
your BMI is:21.133.
 this corresponds to weight category:overweight.
 your BMI is:20.499.
 this corresponds to weight category:overweight.

我们可以对这个函数做一些改变使他能同时对几个个体进行计算,注意保留字NULL,和函数is.null()的使用(他们能敏锐的处理参变量names)

> BMI<-function(weight,height){
+     bmi<-weight/height^2
+     res<-list(Weight=weight,Height=height,BMI=bmi)
+     return(res)
+ }
> weight.category<-function(bmi,names=NULL){
+     intervals.BMI<-c(15,16.5,18.5,25,30,35,40,41)
+     n<-length(bmi)
+     if(is.null(names)) names<-paste("subject number",1:n)
+     if(length(names)!=n)stop(paste("the vector of'names'must
 be of the length",n))
+     code<-vector("integer",length=n)
+     category<-vector("character",length=n)
+     for(i in 1:n){
+         code[i]<-as.character(rank(c(bmi[i],intervals.BMI), 
ties.method = "max")[1])
+         category[i]<-switch(code[i],"2"="severely underweight","3"="underweight","4"="normal weight","5"="overweight",
"6"="moderate obesity","7"="severely obesity","8"="morbid obesity")
+         cat(paste(names[i],"your BMI is:",round(bmi[i],3)," this 
corresponds to weight category:",category[i],sep="")) }}
> weight.category(BMI(c(70,74),c(1.82,1.90))$BMI)
subject number 1your BMI is:21.133 this corresponds to 
weight category:normal weightsubject number 2your BMI 
is:20.499 this corresponds to weight category:normal weight

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值