R 中使用 `UseMethod()` 与 `inherits()` 来确定对象的类

2024-05-16

如果我需要根据 R 对象的类以不同的方式处理它们,我可以使用if and else在单个函数内:

foo <- function (x) {
  if (inherits(x, 'list')) {
    # Foo the list
  } else if (inherits(x, 'numeric')) {
    # Foo the numeric
  } else {
    # Throw an error
  }
}

或者我可以定义一个方法:

foo <- function (x) UseMethod('foo')

foo.list <- function (x) {
  # Foo the list
}
foo.numeric <- function (x) {
  # Foo the numeric
}

每种方法有什么优点?对性能有影响吗?


好吧,回答这个问题需要一些背景知识(在我看来)......

在 R 中,当您拥有用户定义的对象结构或诸如因子向量或数据框之类的对象时,对象的类是显式的,其中其他属性在对象本身的处理中发挥着重要作用(例如,级别)因子向量的标签或数据框中的变量名称是可修改的属性,它们在访问每个对象的观察结果中发挥主要作用。

但请注意,基本 R 对象(例如向量、矩阵和数组)是隐式分类的,这意味着该类不使用属性函数来标识。无论是隐式的还是显式的,都可以使用特定于属性的函数类来检索给定对象的类。

当泛型函数foo被应用到一个object对于类属性 c("first", "second"),系统会搜索名为 foo.first 的函数,如果找到,则将其应用于对象。如果没有找到这样的函数,则调用一个函数foo.second已尝试。如果没有类名产生合适的函数,则该函数foo.default已使用(如果存在)。如果没有class属性,则尝试隐式类,然后default method.

函数 class 打印对象继承的类名称向量。

class <- 设置对象继承的类。

继承()指示它的第一个参数是否继承自任何指定的类what争论。方法调度是根据泛型函数的第一个参数的类进行的。如果哪个为 TRUE,则与返回的长度相同的整数向量。每个元素表示与what的元素匹配的class(x)中的位置;零表示不匹配。如果which为FALSE,则如果what中的任何名称与任何类匹配,则inheritance返回TRUE。

All but 继承()是原始函数。

注意事项

好的,现在让我们以相反的顺序考虑您的示例......

foo <- function (x) UseMethod('foo')

foo.list <- function (x) {
  # Foo the list
}
foo.numeric <- function (x) {
  # Foo the numeric
}

现在如果我们使用函数methods()

methods(foo)
[1] foo.list    foo.numeric
see '?methods' for accessing help and source code
> getS3method('foo','list')
function (x) {
  # Foo the list
}

因此我们有一堂课foo和两个相关方法foo.list and foo.numeric。因此,我们现在知道该类foo,有方法支持list and numeric运营。

好的,现在让我们考虑你的第一个例子......

function (x) {
  if (inherits(x, 'list')) {
    # Foo the list
    print(paste0("List: ", x))
  } else if (inherits(x, 'numeric')) {
    # Foo the numeric
    print(paste0("Numeric: ", x))
  } else {
    # Throw an error
    print(paste0("Unhandled - Sorry!"))
  }
}

问题是这不是 s3 类,而是 R 函数。如果你跑methods()反对foo它返回“未找到方法”

> methods(foo)
no methods found
> getS3method('foo','list')
Error in getS3method("foo", "list") : no function 'foo' could be found

那么第二个例子中发生了什么?继承()操作与参数的类相匹配。继承() ->方法调度是根据泛型函数的第一个参数的类进行的。

所以你的第一个例子只是查找类函数参数 x,没有创建或存在 S3 类。

每种方法有什么优点?对性能有影响吗?

好吧,我在这里有偏见,但对象的类是在 R 中描述实体的最有用的属性之一。您创建的每个对象都通过至少一个类隐式或显式地标识。 R 是一种面向对象的编程语言,这意味着实体存储为对象并具有作用于它们的方法。

所以我认为第二种方法是可行的。为什么?因为您真正按照预期使用了语言构造。使用继承()的第一种方法明显感觉像是一种黑客攻击。从我个人的角度来看,可读性是理解的关键,因此我担心阅读第一个示例的人可能会问“为什么他们(程序员)采用上述方法,我错过了什么?”。我担心的是要避免复杂性,因为它会妨碍代码理解。因此,保持简单有利于代码理解。

就代码性能而言,if-else 解析器通常比对象查找模型更快,尽管查找模型并不等同于类映射过程,因此我觉得在这种情况下性能问题很难回答。为什么?这两种方法是不同的.

这里推荐几本书:

  1. R Inferno 帕特里克·伯恩斯 https://www.burns-stat.com/pages/Tutor/R_inferno.pdf
  2. 高级 R,作者:Hadley Wickham https://adv-r.hadley.nz/
  3. R 适合所有人:高级分析和图形
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R 中使用 `UseMethod()` 与 `inherits()` 来确定对象的类 的相关文章

  • 我应该使用课程吗? (Python)

    我正在尝试编写一个包含一些数学函数的小型 Python 模块 例如 它可能包含如下函数 def quad x a b c return a x 2 b x c 您可能会注意到它包含几个参数 即a b c 除了变量x 现在 如果我将其放入文件
  • 从命令行运行 R 代码 (Windows)

    我在名为 analysis r 的文件中有一些 R 代码 我希望能够从命令行 CMD 运行该文件中的代码 而无需通过 R 终端 并且我还希望能够传递参数并在我的代码中使用这些参数 例如就像下面的伪代码 C gt execute r scri
  • 在 R 中创建虚拟变量,排除某些情况为 NA

    我的数据看起来像这样 V1 V2 A 0 B 1 C 2 D 3 E 4 F 5 G 9 我想创建一个虚拟变量R where 0 1 1 2 3 4 and NA 0 5 9 应该很简单 有人可以帮忙吗 我们可以转换V2 into a fa
  • 在 R 格子包中微调点图

    我正在尝试为不同的数据集和不同的算法绘制一堆 ROC 区域 我有三个变量 方案 指定所使用的算法 数据集 是正在测试算法的数据集 以及 Area under ROC 我正在 R 中使用lattice库 命令如下 点图 方案 Area und
  • 使用 R 选择第一个非 NA 值

    df lt data frame ID c 1 1 1 2 3 3 3 test c NA 5 5 6 4 NA 7 3 NA 10 9 我想创建一个名为 value 的变量 它是每个单独 ID 测试的第一个非 NA 值 对于只有NA的个体
  • 在 Objective C 的类方法中引用类本身

    我希望我没有跳过 ObjC 手册中的这一部分 但是是否可以从类的一个类方法中引用该类 就像在 PHP 中一样 您将使用 this 来引用当前实例 而 self 引用实例的类 this 的 ObjC 等价物将是 self 那么 PHP 的 s
  • 将阴影区域添加到五分位数之间的直方图中

    All 我有一个包含 2 个直方图的图表 其中我还绘制了代表第 20 40 60 和 80 个百分位数的线条 下面的代码使用虚拟数据重现了类似的图表 data lt rbind data frame x rnorm 1000 0 1 g o
  • 文本挖掘 pdf 文件/词频问题

    我正在尝试挖掘一篇具有丰富 pdf 编码和图表的文章的 pdf 我注意到 当我挖掘一些 pdf 文档时 我得到的高频词是 phi taeoe toe sigma gamma 等 它与某些 pdf 文档配合良好 但与其他文档配合使用时却得到这
  • 如何从 R keras 中的类似生成器的数据中评估()和预测()

    我有以下代码 数据集可以下载here https www dropbox com s qjt5o31oyqj10m8 data tar gz dl 0 or here https www kaggle com c dogs vs cats
  • 如何在 R 或 Python 中制作旭日图?

    到目前为止 我一直无法找到一个可以创建旭日图的 R 库约翰 斯塔斯科 http www cc gatech edu gvu ii sunburst 有人知道如何在 R 或 Python 中实现这一点吗 在极坐标投影中使用 matplotli
  • 如何在 R 中匹配多个 ggplot2 图中的调色板?

    自从被问到这个问题以来已经有一段时间了 但我知道一个事实 我很快就会提取新数据 我想弄清楚如何用这种技术来绘制它 看起来评论和答案中的人知道如何做到这一点 但我无法完全弄清楚所给我的内容 还有人想尝试一下吗 我正在尝试使用具有多个级别的因子
  • 多次重定义错误

    在了解了有关类和指针的更多信息后 我重构了一个程序并删除了超过 200 行代码 在此过程中创建了另外两个类 Location and Piece 问题是 在编译完所有内容后 链接器抱怨构造函数Piece被定义了多次 有很多错误 In fun
  • R:如何获取该月的周数

    我是 R 新手 我想要该日期所属月份的周数 通过使用以下代码 gt CurrentDate lt Sys Date gt Week Number lt format CurrentDate format U gt Week Number 3
  • 投资决策:R中的NPV、IRR、PB计算

    我正在尝试计算不同数量项目的净现值 NPV 内部收益率 IRR 和投资回收期 PB 时间 以评估哪个投资项目提供最佳回报 到目前为止 我可以为每个项目单独计算几行代码 但我想做的是 编写一个函数 它接受一个包含许多不同项目及其现金流的矩阵
  • read_html(url) 和 read_html(content(GET(url), "text")) 之间的区别

    我正在看这个很棒的答案 https stackoverflow com a 58211397 3502164 https stackoverflow com a 58211397 3502164 解决方案的开头包括 library httr
  • 不能从模板 C++ 类继承[重复]

    这个问题在这里已经有答案了 我不知道这里出了什么问题 也许有人可以帮助我 我想继承我的新班级MyDictionary来自模板抽象类dictionary 我有这样的代码 字典 h ifndef UNTITLED CPP DICTIONARY
  • applyStrategy 错误

    我是R新手 最近运行后遇到以下错误applyStrategy函数来自quantstrat包裹 Error in eval expr envir enclos object signal not found Error in colnames
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • R:使用 tidyverse 将 NA 替换为 df 中的其他变量

    我想使用 tidyverse 替换 df 中的 NA 值 我想要的值应该从其他列中计算出来 input ID X1 X2 X3 A 0 96 NA 0 97 B 1 00 NA 1 01 C 0 98 0 03 NA A 1 00 NA 1
  • PHP 中的 -> 和 :: 有什么区别?

    这个东西困扰我好久了 一直找不到 在 php 中使用 和 gt 之间的类有什么区别 让我举个例子 想象一个名为 MyClass 的类 该类中有一个函数 myFunction 使用有什么区别 MyClass myclass new MyCla

随机推荐

  • 从时间列表中查找最接近的时间

    所以 这是场景 我有一个带有创建时间的文件 我想从该文件的创建时间最接近或相等的时间列表中选择一个时间 完成此操作的最佳方法是什么 var closestTime listOfTimes OrderBy t gt Math Abs t fi
  • 时间序列数据预处理 - numpy strides 技巧以节省内存

    我正在预处理一个时间序列数据集 将其形状从二维 数据点 特征 更改为三维 数据点 时间窗口 特征 在这样的视角中 时间窗口 有时也称为回顾 指示作为输入变量来预测下一个时间段的先前时间步长 数据点的数量 换句话说 时间窗口是机器学习算法在对
  • 添加与SDN4 + REST中另一个节点的关系

    我构建了一个简单的 SDN4 REST API 一个端点 名为player 包含一组属性 每个玩家都有一个Set
  • Android - 正确使用 invalidateOptionsMenu()

    我一直在寻找很多invalidateOptionsMenu 我知道它的作用 但我想不出这种方法在现实生活中有用的任何例子 我的意思是 例如 假设我们要添加一个新的MenuItem to our ActionBar 我们可以简单地获取菜单on
  • 使用 # 时锚点 标签在 Chrome 中不起作用

    这是我在页面上使用的代码 li a href explore Sound Sound a li 在所有页面上出现的菜单中 a a 在我想要链接的页面上 我尝试过使用 id 将内容添加到标签中 但仅在 Chrome 中 浏览器不会向下滚动到该
  • 从 PCAP 嗅探重建数据

    我试图通过 libpcap 嗅探 HTTP 数据 并在处理 TCP 有效负载后获取所有 http 内容 标头 有效负载 根据我的讨论编写 http 嗅探器 或任何其他应用程序级嗅探器 https stackoverflow com ques
  • Oracle 按月滚动或运行总计

    目标 每个月末所有报表的滚动 运行总计 Code select TRUNC ACTHX STMT HX STMT DATE MM AS MNTH COUNT ACTHX INVOICE as STMTS from ACTHX group b
  • 为什么我的 NHibernate 包集合没有动态设置子项的“父 ID”?

    我有一个新对象 其中包含一些作为 IList 属性的新对象的集合 我通过sql探查器看到正在执行两个插入查询 一个用于父级 它具有新的guid id 另一个用于子级 但是 引用父级的子级上的外键是一个空guid 这是我在父级上的映射
  • 如何包装内在组件,保留大部分 Props?

    我想用我自己的 React 功能组件包装一个标准按钮 但我希望新组件的用户能够设置 几乎所有底层按钮的道具 当然 我想保持正确的打字 所以如果 WrappedButton 包含一个button then
  • 冒泡可用于图像加载事件吗?

    我可以用吗 window addEventListner 某种程度上来说 我所有的图像都有一个display none 图像加载后 我想设置display inline 这样我就可以规范下载图像时显示的内容 在这种情况下 我无法预加载图像
  • 在尝试使用 GPS 之前如何检查 GPS 是否已启用

    我有以下代码 但效果不好 因为有时 GPS 需要很长时间 我该如何执行以下操作 检查GPS是否启用 如果启用了 GPS 请使用 GPS 否则请使用网络提供商 如果 GPS 时间超过 30 秒 请使用网络 我可以使用时间或 Thread sl
  • 生成 equals 和 hashcode 时忽略属性

    假设我有一个类 Customer public class Customer private String firstName private String lastName private String doNotAddMeToEqual
  • 使用 ELMAH 记录 WCF 服务的异常

    我们正在使用优秀的ELMAH http code google com p elmah处理 ASP NET 3 5 Web 应用程序中未处理的异常 这对于除使用 REST 功能使用的 WCF 服务之外的所有站点都非常有效 当操作方法中发生应
  • 使用标签或 href 传递 Django 数据

    我有一个包含链接的表 当单击该链接进行更多操作时 我想将一些数据传递给我的函数 my html table tbody for query in queries tr td value a href internal my func que
  • 使用 cordova cli 构建时的 Android 安装位置

    我正在使用 cordova CLI 工具构建一个大型 cordova phonegap 应用程序 我需要 AndroidManifest xml 文件中的 installLocation 具有 installLocation auto 或p
  • 非法使用break语句; javascript

    当这个变量达到一定数量时 我希望循环停止 但我不断收到错误 未捕获的语法错误 非法的中断语句 function loop if isPlaying jet1 draw drawAllEnemies requestAnimFrame loop
  • 如何调试在发布版本中优化的变量

    我用的是VS2010 我的调试版本工作正常 但我的发布版本不断崩溃 因此 在发布版本模式下 我右键单击该项目 选择 调试 然后选择 启动新实例 此时我看到我声明的一个数组 int ma 4 1 2 8 4 永远不会被初始化 关于可能发生的事
  • 如何从 ruby​​ 中的字符串中删除所有非数字?

    用户输入数字的形式如下 1 800 432 4567 800 432 4567 800 432 4566 800 432 4567 1 800 432 4567 800 432 4567 我希望所有这些都变成没有特殊字符的剥离版本 例如18
  • 从 PL/SQL 调用 shell 脚本,但 shell 以 grid 用户而非 oracle 身份执行

    我正在尝试使用 Runtime getRuntime exec 从 Oracle 数据库内部执行 shell 脚本 在 Red Hat 5 5 上运行的 Oracle 11 2 0 4 EE CREATE OR REPLACE proced
  • R 中使用 `UseMethod()` 与 `inherits()` 来确定对象的类

    如果我需要根据 R 对象的类以不同的方式处理它们 我可以使用if and else在单个函数内 foo lt function x if inherits x list Foo the list else if inherits x num