R语言函数

2023-10-31

  R语言实际上是函数的集合,用户可以使用base,stats等包中的基本函数,也可以自己编写函数完成一定的功能。但是初学者往往认为编写R函数十分困难,或者难以理解。这里对如何编写R函数进行简要的介绍。


   函数是对一些程序语句的封装。换句话说,编写函数,可以减少人们对重复代码书写,从而让R脚本程序更为简洁,高效。同时也增加了可读性。一个函数往往完成一项特定的功能。例如,求标准差sd,求平均值,求生物多样性指数等。R数据分析,就是依靠调用各种函数来完成的。但是编写函数也不是轻而易举就能完成的,需要首先经过大量的编程训练。特别是对R中数据的类型,逻辑判别、下标、循环等内容有一定了解之后,才好开始编写函数。 对于初学者来说,最好的方法就是研究现有的R函数。因为R程序包都是开源的,所有代码可见。研究现有的R函数能够使编程水平迅速提高。

   R函数无需首先声明变量的类型,大部分情况下不需要进行初始化。一个完整的R函数,需要包括函数名称,函数声明,函数参数以及函数体几部分。

1. 函数名称,即要编写的函数名称,这一名称就作为将来调用R函数的依据。
2. 函数声明,包括 <- function, 即声明该对象的类型为函数。
3. 函数参数,这里是输入的数据,函数参数是一个虚拟出来的一个对象。函数参数所等于的数据,就是在函数体内部将要处理的值,或者对应的数据类型。 函数体内部的程序语句进行数据处理,就是对参数的值进行处理 ,这种处理只在调用函数的时候才会发生。函数的参数可以有多种类型。R help的界面对每个函数,及其参数的意义及所需的数据类型都进行了说明。
4. 函数体
常常包括三部分.
(1). 异常处理
输入的数据不能满足函数计算的要求,或者类型不符, 这时候一定要设计相应的机制告诉用户,输入的数据在什么地方有错误。 错误又分为两种。
第一种, 如果输入的数据错误不是很严重,可以经过转换,变为符合处理要求的数据时, 此时只需要给用户一个提醒,告知数据类型不符,但是函数本身已经 进行了相应的转换。
第二种,数据完全不符合要求,这种情况下,就 要终止函数的运行,而告知因为什么,函数不能运行。这样,用户在 使用函数的情况先才不至于茫然。
(2). 运算过程
包括具体的运算步骤。 运算过程和该函数要完成的功能有关。
R运算过程中,应该尽量减少循环的使用,特别是嵌套循环。R提供了 apply,replicate等一系列函数,来代替循环,应该尽量应用这些函数, 提高效率。 如果在R中实在太慢,那么核心部分只能依靠C或者Fortran 等语言编写,然后再用R调用这些编译好的模块,达到更高的效率。
运算过程中,需要大量用到if等条件作为判别的标准。if和while都是需要数据TRUE/FALSE这样的逻辑类型变量,这就意味着,if内部,往往是对条件的判别,例如 is.na, is.matrix, is.numeric等等,或者对大小的比较,如,if(x > 0), if(x == 1), if(length(x)== 3)等等。if后面,如果是1行,则花括号可以省略,否则就必须要将所有的语句都放在花括号中。这和循环是一致的。

例子1
## if与条件判断
fun.test <- function(a, b, method = "add"){
    if(method == "add") { ## 如果if或者for/while;
        res <- a + b ## 等后面的语句只有一行,则无需使用花括号。
}
    if(method == "subtract"){
        res <- a - b
    }
    return(res) ## 返回值
}
### 检验结果
fun.test(a = 10, b = 8, method = "add")
fun.test(a = 10, b = 8, method = "substract")
 
for循环有些时候是必须要用到的,for循环内部,往往需要用下标,访问数据内的一定元素,例如向量内的元素,这时候用方括号表示。一维的数据组合,或者数组,常常称为向量。二维的数据组合,往往称为矩阵,或者数据框。具体的访问方式主要是方括号内部有没有逗号的区别。for循环或者while循环有时候让人觉得比较困惑,可能需要专门的时间进行讲解。

例2
### for循环与算法
test.sum <- function(x)
{
    res <- 0 ### 设置初始值,在第一次循环的时候使用
    for(i in 1:length(x)){
        res <- res + x[i] ## 这部分是算法的核心,
##总是总右面开始计算,结果存到左边的对象
    }
    return(res)
}
 

### 检验函数
a <- c(1,2,1,6,1,8,9,8)
test.sum(a)
sum(a)
 
无论是什么样的函数,算法才是最关键的。往往需要巧妙得设计算法,让函数快捷高效。

(3). 返回值。
返回值就是函数给出的结果。打个比方,编写一个函数,就像自己攒一个机器,例如现在攒好 一台豆浆机,该豆浆机要求输入大豆,输入的大豆就是参数, 返回的结果,就是豆浆。如果该豆浆机需要不停地输入大豆, 而不能产出豆浆,这样的机器就一定会被扔掉。函数也是一样的, 需要给出返回值。 R中默认的情况是将最后一句作为返回值。但是为了函数的可读性起见,应该尽量指名返回值。返回值用return()函数给出。 函数在内部处理过程中,一旦遇到return(),就会终止运行, 将return()内的数据作为函数处理的结果给出。
下面举例说明R函数的编写方法。

例3 计算标准差
sd2 <- function(x)
{
   # 异常处理,当输入的数据不是数值类型时报错
   if(!is.numeric(x)){
      stop("the input data must be numeric!\n")
   }
   # 异常处理,当仅输入一个数据的时候,告知不能计算标准差
   if(length(x) == 1){
      stop("can not compute sd for one number,
           a numeric vector required.\n")
   }
   ## 初始化一个临时向量,保存循环的结果,
   ## 求每个值与平均值的平方
   x2 <- c()
   ## 求该向量的平均值
   meanx <- mean(x)
   ## 循环
   for(i in 1:length(x)){
       xn <- x[i] - meanx
       x2[i] <- xn^2
   }
      ## 求总平方和
   sum2 <- sum(x2)
   # 计算标准差
   sd <- sqrt(sum2/(length(x)-1))
   # 返回值
   return(sd)
}
 
## 程序的检验
## 正常的情况
sd2(c(2,6,4,9,12))
## 一个数值的情况
sd2(3)
## 输入数据不为数值类型时
sd2(c("1", "2"))
 
这样,一个完整的函数就编写完成了。当然,实际情况下,函数往往更为复杂,可能要上百行。但是好的编程人员往往将复杂的函数编写成小的函数。以便于程序的修改和维护,即使其中出现错误,也很好修改。

再有就是编写R函数时一定要注意缩进,编辑器用Notepad++, TinnR, Rstudio等,同时用等距字体(如Consolas, Courier new等)和语法高亮显示。这样便于快速寻找到其中

的错误。


参考https://www.douban.com/note/279077707/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R语言函数 的相关文章

随机推荐

  • 小技巧(5):将TT100K数据集转成VOC格式,并且用Python脚本选出45类超过100张的图片和XML

    上一篇 小技巧 4 将txt中的某两列数据写入csv文件中 制作图像分类标签 文章目录 一 相关准备 1 1 下载数据集 1 2 下载代码文件 1 3 将相关文件移入代码文件 二 创建标准的VOC文件夹 三 生成整个数据集的XML文件 四
  • leetcode-第247场周赛-5798循环轮转矩阵(模拟题)

    5798 循环轮转矩阵 模拟题 题目链接 https leetcode cn com problems cyclically rotating a grid 题目 给你一个大小为 m x n 的整数矩阵 grid 其中 m 和 n 都是 偶
  • Code=201 “Siri and Dictation are disabled“

    iOS 15 之前的语音识别是使用SpeechKit和AVFoundation两个框架来配合使用 其中主要的类有SFSpeechRecognizer SFSpeechAudioBufferRecognitionRequest SFSpeec
  • SSHLibrary本地远程访问LINUX遇Incompatible ssh peer错误

    FAIL SSHException Incompatible ssh peer no acceptable kex algorithm 使用python写了段脚本 远程访问LINUX主机 同样的一段脚本 访问主机A可以 访问主机B就报标题中
  • QtModbus Serial 简单示例

    来自QQ群 Linux 技术分享 311078264 打开链接加入QQ群 https jq qq com wv 1027 k 5Gr3bAx 此文档由elikang整理 为了文章简单直接 许多细节未能在文章中体现 如有疑问请进群讨论 Qt
  • 浮动图标代码

    lt html xmlns http www w3 org 1999 xhtml gt lt head gt lt title gt wahaha lt meta
  • 如何在O(1)时间删除链表指定节点(Java实现)

    声明 题目背景为剑指offer 13 在O 1 时间删除链表节点 给出一个链表如下 删除链表中给定节点 我想最容易想到的方法就是循环遍历 假设想删除节点toBeDeleted 我们先遍历链表 找到节点的下一节点为toBeDeleted的节点
  • python之pyAudioAnalysis:音频特征提取分析文档示例详解

    PyAudioAnalysis是一个开源的Python库 用于从音频文件中提取特征并进行分析 它提供了一系列音频处理函数 可以帮助开发者实现音频分类 情感识别 语音分析等多种任务 在本文中 我们将详细介绍如何使用PyAudioAnalysi
  • 适配器模式和装饰器模式区别

    适配器模式和装饰器模式都可以在原类文件方法的基础上修改 增强 但侧重点不一样 适配器模式重在将一个接口转换为另一个接口 装饰器模式侧重对原类文件方法的增强 但接口还是同一个接口 适配器模式 适配器模式 解决原类文件 适配者 和现有需求 目标
  • ESP8266 WIFI模块学习之路(7)——自写Android手机APP接受单片机数据

    上一篇是写关于自写Android手机APP给单片机下发数据的 这次我将写一下APP如何接受单片机数据 其实使用调试助手 或者别人开的的APP同样能够实现接受单片机数据 但想学习的 我还是建议能够自己写一个Android软件 这样从底层到上层
  • 中间件的介绍

    1 1 什么是中间件 中间件是介于应用系统和系统软件之间的一类软件 他使用系统软件所提供的基础服务 衔接网络上应用系统的各个部分或不同的应用 能够达到资源共享 功能共享的目的 例如MySQL就可以看作是具备中间件特性的一种技术 中间件技术必
  • mysql8查看用户密码_mysql8用户管理

    查看当前登录用户 创建用户 create user 用户名 主机地址 identified with mysql native password by 密码 修改密码 alter user 用户名 主机地址 identified with
  • cnocr避坑指南

    今天用我的win7电脑运行我的一个python程序 让我安装cnocr 于是我就pip install cnocr 安装成功 继续运行 却出现mxnet的问题 一堆它的 dll文件没有 反复卸载重装 没得救 看了一个文章 也是这个问题 就想
  • Java教程:如何读取服务器文件并推送到前端并下载,图片格式以浏览器渲染模式

    起因 在我们做文件上传时 通常会保存文件的相对路径在数据库中 然后返回前端http访问路径 来对文件进行下载或图片预览功能 但是有时候我们并不想直接返回文件访问地址给前端 这就用到了Java当中的文件输入输出流 将文件以流的方式响应给浏览器
  • 【C语言】详解qsort函数使用和模拟实现

    一 qsort函数的使用 qsort的功能 qsort函数是C语言标准提供的排序函数 使用qsort函数需要引用头文件 include
  • h5 video方法,事件,属性详解

    闲下来的的时间里 我一直总结之前学习过的知识 今天到video 发现对它还是不够熟悉 于是重新学习一遍 举个例子
  • [云原生专题-37]:K8S - 核心概念 - 存储抽象- 搭建NFS网络文件系统与常见操作命令

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 122828322 目录 第1步 NFS
  • 怎样用python通达信接口写一个股票自动买卖的程序?

    方法一 前期的数据抓取和分析python都写好了 所以就差交易指令接口了 对于散户投资者来说 正规的法子是愿意给接口的券商 但是需要很高的开户费 而且只有lts ctp这样的c 接口 没有python版就需要用户自己去封装 方法二 wind
  • js抽奖(随机抽奖

    js抽奖 随机抽奖 默认抽奖结果 效果示例图 代码块 效果示例图 代码块
  • R语言函数

    R语言实际上是函数的集合 用户可以使用base stats等包中的基本函数 也可以自己编写函数完成一定的功能 但是初学者往往认为编写R函数十分困难 或者难以理解 这里对如何编写R函数进行简要的介绍 函数是对一些程序语句的封装 换句话说 编写