问题标签 [s4]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
r - 了解 R 中的 switch() 函数?
由 Venables 和 Ripley 编写的《统计与计算》一书有一个示例,说明在通用群函数 Math 的“多项式”类的对象上定义方法函数。数学是一个组函数,包含一些组件函数,包括 abs、acos、acosh、...
下面是书中提到的为组泛型函数Math定义方法函数的代码(注意代码是针对S4类(新式R/S类)):
我知道使用 setMethod() 我们正在为通用函数 Math 定义一个方法函数,当它在“多项式”类的对象上调用时。你能解释一下 switch 在这里做什么吗?我阅读了有关开关的 R 帮助,但仍然难以理解以下部分:
请注意,上面的多项式函数是一个构造函数,用于创建“多项式”类的对象。
r - 将 S4 R 对象分配给矩阵:为什么会这样?
我已经定义了一个名为 的 S4 类cell
,我想将其实例分配给一个 3x3 矩阵(选择 3x3 是为了确定性)。以下代码适用于 R 版本 2.15.1,并在一个简单的情况下重现了 R 的行为。我发现我可以将类型的对象分配cell
给一个矩阵,该矩阵的条目首先用 初始化为空列表matrix(list(),3,3)
,然后我将新的类型对象分配给cell
条目。问题是:它为什么有效?
这是一个示例会话:
createGrid()
通过将空列表分配更改为进行修改grid<- matrix(0,3,3)
将产生错误:
这并不奇怪,但它确实让我找到了工作代码。以下尝试使用 3x3 单元格矩阵定义new()
失败:
问题是,为什么第一个有效?
r - S4 对象组合不当行为?
我有以下问题(代码如下):我有两个 S4 类,让我们用A
和指定它们B
。该类B
有一个 A 型对象列表,名为a.list
. 该类A
有一个名为 的方法test()
。然后,我创建一个类型为 的对象A
,称为a
,和一个类型为 的对象B
,b
然后我将a
对象插入到 的列表中b@a.list
。
当我提取a
对象并在其中使用该test
方法时,会发生以下错误:
但是我直接在a
对象中使用方法,一切正常。
知道我做错了什么吗?
提前致谢
现在,代码:
再次感谢...
r - 从关联对象中检索定义 S4 引用类的实际源表达式
简而言之(实际问题)
如何访问定义 S4 引用类的实际源代码/表达式?setRefClass
(请参阅)或返回的对象(因此在获取它之后,而不是通过调查实际源文件)?getClass("MyClass")
getRefClass("MyClass")
我做的功课
由于一切都是 R 中的对象,我可以检索源代码/表达式
1)通过简单地调查相应对象的常规功能:
2)通过获取特定方法的方法对象的形式方法selectMethod
:
但是 S4 参考类的情况似乎有所不同:
我似乎找不到存储准确定义类的实际源代码/表达式的属性。
只是为了确保:这个表达式是我想要访问的
背景/动机
我经常使用 S4 引用类 ( ),因此像类继承?setRefClass
这样的OOP 方面在我的日常工作中扮演着重要角色。我还遵循“每个文件一个定义”的范例,以使事情井井有条,因此各种类定义存储在单独的文件中,其中文件名对应于各个类的名称。
与生活中的一切一样,这种方法有一些优点,但也有一些固有的缺点:
看点一
无论长短,您最终都会得到一个与各个源文件的字母文件顺序不再匹配的继承结构。因此,简单地一个接一个地获取一个文件将导致在某个特定点出现错误,其中一些所需的超类尚未被获取。
class_A.R
是 folder 中的第一个文件classes
,但为了获取它,我们首先需要获取源class_B.R
(因为该文件定义了 class B
),这反过来又需要 class C
,因此需要先获取class_C.R
.
因此,正确的排序规则是:
方面2
对于某些任务,您确实想要/需要“每个文件多个定义”范例:在并行化时快速轻松地将必要的对象/函数/类分配给工作进程,在实际构建包时组织代码等。
广告方面 1
我不喜欢保留某种手动整理参考来指定正确的采购顺序的想法,因为我认为这是计算机可以轻松为我完成的工作(找出正确的整理)。您在这里唯一需要做的就是找出每个类的超类(某种依赖关系),然后检索正确的排序规则就是小菜一碟。
编辑
如果有人感兴趣:我确实为此提出了一种工作方法。如果您想查看一些代码,请给我留言。它基于解析(不评估)相应的类 def 源文件,以调查contains
列出超类的参数的值。然后对这些超类的源文件递归地重复整个过程,直到最终得到正确的排序规则。也不是那么费时间。
这是大纲:
广告方面 2
我也不喜欢手动复制和粘贴,所以我实现了一个例程,允许我将存储在单个文件中或从各个对象中提取的源代码合并到单个“合并”文件(通过deparse(<source_code_expression>)
和write(..., append=TRUE)
)。至于类,正确的排序规则在这里也很重要,否则当您尝试获取合并文件时会再次出现错误。
对于这两个方面,能够选择如何获取类/函数/方法的实际源代码/表达式会很好:
- 或者基于调查存储在相应源文件中的代码 (
parse(file=*)
) - 或基于直接从相应对象访问所需信息。
第二个选项将是上述实际问题的链接。
r - 将内容存储到所需对象
我有一个这样的向量:
我有另一个这样的向量:
我在这里尝试做的是加载 RData 文件,然后使用相同的文件名将它们保存回来,但对象应该是 vec1 的对象。
但它给了我错误,说"incompatible types"
我也尝试像这样更改角色对象的类:
其中 myclass 是 S4 类型对象的类。
有没有办法在 R 中做到这一点???
r - 在 R 中学习面向对象编程的有用书籍?
我在 R-bloggers 上阅读了一篇关于“使用 S4 类在 R 中进行面向对象编程”的有趣帖子。Venables 和 Ripley 编写的“统计和计算”一书有一些章节介绍了 S 和 R 中的 S3 类和 S4 类,并且有在理解 R 中面向对象编程的概念方面对我很有用。
您是否知道任何有用的书籍更详细地介绍了 R 中的面向对象编程,并附有 R 博主中的示例?
r - 链接到 .rd 文件中的 S4 方法?
我正在编写一个带有 S4 类的包,并且我已经为该类编写了as.POSIXct
方法as.POSIXlt
。我已经编写了文档,一切看起来都很好,除了我想引用as.POSIXct
文档中的方法,as.POSIXlt
反之亦然。我试过\S4method{coerce}{abc, POSIXct}(from, to)
, (其中 'abc' 是 S4 类),但这应该只放在该\usage
部分中,这不是我想要的。有没有办法做到这一点?对我来说这似乎很奇怪,这不会被允许。
我意识到可以组合这些 .rd 文件并避免这个问题,但我正在尝试尽可能多地了解 R 中的类和包,所以无论如何这对我来说很感兴趣。
这是 .Rd 文件之一的骨架:
倒数第四行是引起问题的行。
r - 在单个函数中结合 S4 和 S3 方法
什么是定义应该具有 S3 和 S4 类实现的通用功能的好方法?我一直在使用这样的东西:
这成功了:
有没有一种“本机”的方式来实现这一点?我知道我们可以使用 为 S3 类定义 S4 方法setOldClass
,但是如果一个对象有多个类,我们就会失去 S3 方法的调度。例如(在干净的会话中):
object
这失败了,因为在这种情况下,第二类bar
被忽略了。我们可能可以通过在foo
and之间定义正式的 S4 继承来解决这个问题bar
,但是对于我的应用程序,我宁愿myfun.bar
在具有类的 S3 对象上开箱即用bar
。
无论哪种方式,事情都变得一团糟,我想这是一个常见的问题,所以可能有更好的方法来做到这一点?
r - 使用正式方法定义的 S3 对象的 S3 样式分派
与这个问题有关,但略有不同,希望更清楚。
我正在寻找一种干净的方式来正式注册 S4 和 S3 类的方法,但不依赖于糟糕的 S3-dot-naming-scheme 进行调度。一个例子:
这个例子展示了我们如何test
为类的 S3 对象注册一个方法bar
,而不需要命名函数test.bar
,这很棒。但是,限制是如果我们以这种方式注册方法,它们只会被分派到对象的第一个 S3 类。例如:
这不起作用,因为 S4 方法分派只会尝试类foo
及其超类。如何扩展此示例,以便在找不到合适的方法时自动选择test
方法?例如 S3 风格的调度,但不必重新命名所有内容和?bar
foo
test.foo
test.bar
总而言之:如何创建一个使用正式方法分派的通用函数,但对于具有多个类的 S3 对象,还依赖于对象的第二个、第三个等类。
r - `getClasses()` 中默认环境的模糊变化(标准函数与正式 S4 方法)
关于“环境嵌套”/词法范围,我很难弄清楚这里到底发生了什么:
问题
where
函数中参数的默认值getClasses()
似乎会有所不同,具体取决于getClasses()
是在标准 R 函数中调用还是在正式 S4 方法中调用。它被.externalCallerEnv()
哪个似乎是惰性评估的“对象”控制,从而导致变化(见下面的编辑)
问题
从正式的 S4 方法内部调用时,如何设置与在标准函数内部调用where
时的默认值相同的值?getClasses()
插图
您将在下面找到上述“问题行为”的简短说明
1) 自定义类
我有许多当前来自.GlobalEnv
.
让我们以这一个作为他们所有人的代表
2)列出可用的类
通过 argument where
, functiongetClasses
让我选择寻找类的环境。
以下似乎无处不在.GlobalEnv
,因此找不到我的班级;没关系:
现在我只.GlobalEnv
查找类A
;这也很好:
3) 创建自定义标准查找函数
当我将查找通过getClasses
放入标准函数中时(这只是所需功能的第一部分,我想getClasses()
在该方法内部进行计算,而不是将其返回值作为形式参数传递),一切仍然正常
4) 创建正式的 S4 方法
但是,一旦我将所有内容都放入正式的 S4 方法getClasses()
中,用于查找类的标准环境似乎发生了一些变化
以前,"A" %in% foo1(where=NULL)
是FALSE
(需要),而现在是("A" %in% foo2(where=NULL)
不需要)。TRUE
任何想法如何foo2()
以完全相同的方式表现foo1()
?
编辑 2012-08-29
正如 Josh O'Brien 在下面的评论中指出的那样,这种变化可能是由惰性评估引起的。
调试foo1()
你进入调试跟踪器;点击<RETURN>
4 次,然后输入get("where")
:
在控制台中,点击<RETURN>
1 次,然后键入evList
:
键入Q
以退出当前调试运行
现在再次运行所有内容,但调试调用略有不同
在控制台中,点击<RETURN>
5 次,然后键入evList
:
现在输入get("where")
:
现在where
指向namespace:methods
调试`foo2()'
你进入调试跟踪器;点击<RETURN>
4 次,然后输入get("where")
:
然后点击<RETURN>
1 次,然后键入evList
:
键入Q
以退出当前调试运行
现在再次运行所有内容,但调试调用略有不同
点击<RETURN>
5 次,然后输入evList
:
现在输入get("where")
:
evList
并注意与where
之前的调试运行相比的不同值。键入Q
以退出当前调试运行。
这对我来说似乎有些奇怪,但从语言设计者的角度来看可能是有道理的。一旦我知道如何显式设置where
为指向与namespace:methods
.