所以我在R中有一个spatialpolygons对象; 但我不确定为什么我无法从中检索"区域"槽.
这是我的R会议:
> spatialpolygons
An object of class "SpatialPolygons"
Slot "polygons":
[[1]]
An object of class "Polygons"
Slot "Polygons":
[[1]]
An object of class "Polygon"
Slot "labpt":
[1] 20.50516 57.72918
Slot "area":
[1] 36.85484
Slot "hole":
[1] FALSE
Slot "ringDir":
[1] 1
Slot "coords":
[,1] [,2]
[1,] 16.48438 59.73633
[2,] 22.59277 61.14258
[3,] 24.74609 55.03418
[4,] 17.49512 55.12207
[5,] 16.48438 59.73633
Slot "plotOrder":
[1] 1
Slot "labpt":
[1] 20.50516 57.72918
Slot "ID":
[1] "myMultiPolygons"
Slot "area":
[1] 36.85484
Slot …Run Code Online (Sandbox Code Playgroud) 我已多次遇到以下问题.
假设您有两个类,classA并classB在以下文件中进行了描述classA.R:
#' the class classA
#'
#' This is a class A blabla
#' \section{Slots}{\describe{\item{\code{A}}{a Character}}}
#' @ name classA
#' @rdname classA
#' @exportClass classA
setClass("classA",representation(A="character"))
Run Code Online (Sandbox Code Playgroud)
和 classB.R
#' the class classB
#'
#' This is a class B blabla
#' \section{Slots}{\describe{\item{\code{B}}{an object of class A}}}
#' @ name classB
#' @rdname classB
#' @exportClass classB
setClass("classB",representation(B="classA"))
Run Code Online (Sandbox Code Playgroud)
我相信这些文件是按字母顺序读取的roxygen2,但事实并非如此.如果我尝试构建包,我可能会收到以下错误:
roxygenize("./myExample")
Error in getClass(Class, where = topenv(parent.frame())) :
"ClassA" is not a …Run Code Online (Sandbox Code Playgroud) 我想创建一个包含S4类的不同变量的data.frame.对于像"POSIXlt"这样的内置类(对于日期),这很好用:
as.data.frame(list(id=c(1,2),
date=c(as.POSIXlt('2013-01-01'),as.POSIXlt('2013-01-02'))
Run Code Online (Sandbox Code Playgroud)
但是现在我有一个用户定义的类,让我们说一个名字和年龄的"Person"类:
setClass("person", representation(name="character", age="numeric"))
Run Code Online (Sandbox Code Playgroud)
但是以下失败了:
as.data.frame(list(id=c(1,2), pers=c(new("person", name="John", age=20),
new("person", name="Tom", age=30))))
Run Code Online (Sandbox Code Playgroud)
我还尝试使用人员类重载[...] - 运算符
setMethod(
f = "[",
signature="person",
definition=function(x,i,j,...,drop=TRUE){
initialize(x, name=x@name[i], age = x@age[i])
}
)
Run Code Online (Sandbox Code Playgroud)
这允许类似矢量的行为:
persons = new("person", name=c("John","Tom"), age=c(20,30))
p1 = persons[1]
Run Code Online (Sandbox Code Playgroud)
但仍然有以下失败:
as.data.frame(list(id=c(1,2), pers=persons))
Run Code Online (Sandbox Code Playgroud)
也许我必须重载更多运算符才能将用户定义的类放入数据帧中?我确信,必须有办法做到这一点,因为POSIXlt是一个S4类,它的工作原理!任何使用新R5参考类的解决方案都可以!
我不想把我的所有数据都放到人类中(你可能会问,为什么"id"不是我不使用数据帧的人的成员)!我的想法是,我的data.frame表示一个数据库中的表,其中包含许多不同类型的列,例如字符串,数字......,还有日期,间隔,地理对象等...对于我已经拥有的日期一个解决方案(POSIXlt),用于间隔,地理对象等.我可能需要指定自己的S4/R5类.
非常感谢提前.
有人可以解释为什么在定义新类时重载已注册的旧式S3类上的运算符不能正常工作,并且重载运算符确实有效.
如以下示例所示.
这不起作用.
require(ff)
setOldClass(Classes=c("ff_vector"))
setMethod(
f="*",
signature = signature(e1 = c("ff_vector"), e2 = c("ff_vector")),
definition = function (e1, e2){
print("S3 setOldClass")
e1[] * e2[]
}
)
ff(1:10) * ff(1:10)
Error in ff(1:10) * ff(1:10) : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)
但这很有效.
setClass("myff_vector", representation(x="ff_vector"))
setMethod(
f="*",
signature = signature(e1 = c("myff_vector"), e2 = c("myff_vector")),
definition = function (e1, e2){
print("S4 setOldClass")
e1@x[] * e2@x[]
}
)
new("myff_vector", x = ff(1:10)) * new("myff_vector", x = ff(1:10))
[1] "S4 setOldClass"
[1] 1 …Run Code Online (Sandbox Code Playgroud) 我的S4类有一个多次调用的方法.我注意到执行时间比独立调用类似函数时要慢得多.所以我在我的类中添加了一个带有"function"类型的插槽,并使用该函数而不是方法.下面的示例显示了两种执行此操作的方法,它们都比相应的方法运行得快得多.此外,该示例表明该方法的较低速度不是由于必须从类中检索数据的方法,因为即使它们也这样做,功能也更快.
当然,这种做事方式并不理想.我想知道是否有办法加速方法调度.有什么建议?
setClass(Class = "SpeedTest",
representation = representation(
x = "numeric",
foo1 = "function",
foo2 = "function"
)
)
speedTest <- function(n) {
new("SpeedTest",
x = rnorm(n),
foo1 = function(z) sqrt(abs(z)),
foo2 = function() {}
)
}
setGeneric(
name = "method.foo",
def = function(object) {standardGeneric("method.foo")}
)
setMethod(
f = "method.foo",
signature = "SpeedTest",
definition = function(object) {
sqrt(abs(object@x))
}
)
setGeneric(
name = "create.foo2",
def = function(object) {standardGeneric("create.foo2")}
)
setMethod(
f = "create.foo2",
signature = "SpeedTest",
definition = function(object) { …Run Code Online (Sandbox Code Playgroud) 我是R的新手,并且很难将来自各种来源的信息拼凑起来,这些信息与编写R代码的"好"做法有关.我已经阅读了基本指南,但我一直很难找到最新的信息.
如果给一个对象x,是有办法分类它是否是S3或S4(或"其他")?我已经看过is.object()并isS4(),并可以识别的东西是一个对象(或没有),而且它是一个S4对象(或没有).但是,在我看来,S3对象并不是所有不是S4对象的对象的补充.
因此,如何以编程方式完成这些任务?
这是一个让我烦恼的例子,取自以下的帮助is.object():
a = as.factor(1:3)
is.object(a) # TRUE
isS4(a) # FALSE
Run Code Online (Sandbox Code Playgroud)
这是否意味着这a是一个S3对象?
我想创建一个几乎是数据框架的类,有一些增强功能(额外的功能,额外的属性),我想知道最好的方法是什么.该类基本上是一个数据框,但有一些额外的属性,例如该数据框的模式(下面命名为"form",自动派生,表示为数据框,用于将数据框转换为正确的类型),还有其他几件事.当用户在其他不识别其特殊类型的函数中使用此对象时,我希望它们处理对象的data.frame部分.做这个的最好方式是什么?
我发现的两种方法都不令人满意; 我列出了他们以及我仍然看到并试图解决的问题; 问题是:做我想做的最好的方法是什么?
方法1,使用"data.frame"作为"基础"插槽 (受此SO帖子的启发)
setClass("formhubData", representation(form="data.frame"), contains="data.frame")
fd <- new('formhubData', data.frame(x=c(1,2)), form=data.frame(name='x', type='select one', label='X'))
Run Code Online (Sandbox Code Playgroud)
这种方法允许我做以下事情:
fd$x >> 1 2
names(fd) >> "x"
Run Code Online (Sandbox Code Playgroud)
[更新:事实证明"分解"是由我的环境造成的,我用不同的参数反复调用setClass('formhubData',...).在新的R会话中,以下所有函数都按预期工作.]
但它很快崩溃了:
nrow(fd) >> NULL
colnames(fd) >> NULL
Run Code Online (Sandbox Code Playgroud)
与上面链接的帖子不同,即使简单is.data.frame也不适用于我
is.data.frame >> FALSE
Run Code Online (Sandbox Code Playgroud)
方法2,使用"数据"插槽(灵感来自SP)
setClass("formhubData", representation(data="data.frame", form="data.frame"))
fd <- new('formhubData', data=data.frame(x=c(1,2)), form=data.frame(name='x', type='select one', label='X'))
Run Code Online (Sandbox Code Playgroud)
我失去了默认定义:
fd$x >> NULL
names(fd) >> integer(0)
Run Code Online (Sandbox Code Playgroud)
但是,至少我可以重新定义它们中的大多数(仍然需要了解[,[[等等):
dim.formhubData <- function(x) dim(x@data)
names.formhubData <- function(x) names(x@data)
nrow(fd) >> 2
names(fd) >> "x"
Run Code Online (Sandbox Code Playgroud)
但是,我似乎无法表达这样一个事实:对于任何采用data.frame的方法,我的类应该用作其@data插槽的直通.我觉得这样的事情需要 *.formhubData <- function(x, ...) *(x, …
我正在编写一个S4类,其中内部数据存储在数据库中,该类主要是用于访问和修改数据库中信息的守门员.这个类必须的方法,如getInfoA与getInfoA<-用于提取和设置的某些信息.
我的问题涉及以下案例:
myObject <- new('myClass', db='path/to/database')
getInfoA(myObject)[1:5] <- letters[1:5]
Run Code Online (Sandbox Code Playgroud)
这里的setter在赋值之前是子集的.通常,当数据存储在标准R结构中时,这会自动解决,但是当数据存储在别处时如何正常处理?[<-R中有一个原语,但我不清楚调度是如何进行的,以及在何处以及如何拦截它......
打印一个data.frameS4对象的列表列时是否存在一般问题?或者我只是不走运?
我用git2r包中的对象来讨论这个问题,但维护者Stefan Widgren也指出了这个例子Matrix.我注意到,如果通过发送对象可以打印dplyr::tbl_df().我接受打印不提供S4对象的大量信息; 我要问的是没有错误.
更高的抱负更新:可以保持data.frame类似的质量吗?
library(Matrix)
library(dplyr)
m <- new("dgCMatrix")
isS4(m)
#> [1] TRUE
df <- data.frame(id = 1:2)
df$matrices <- list(m, m)
df
#> Error in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, : first argument must be atomic
tbl_df(df)
#> Source: local data frame [2 x 2]
#>
#> id
#> (int)
#> 1 1
#> 2 2
#> Variables not shown: matrices (list).
## force dplyr …Run Code Online (Sandbox Code Playgroud)