【问题标题】:Proof if S4 objects are identical证明 S4 对象是否相同
【发布时间】:2013-09-03 11:34:52
【问题描述】:

我有两个包含S4 对象的列表。现在我想问一下 list_1 的元素是否包含 list_2 的元素,就像我在下面的字符向量列表示例中所做的那样。

s<-list(a=LETTERS[1:3],b=LETTERS[4:6])
t<-list(n=LETTERS[1:3],v=LETTERS[1:4])
s %in% t

但它是否证明对象是否相同?如果没有,如何在不使用循环的情况下选择list_2中存在的list_1的元素?

【问题讨论】:

  • 我还在投票,我的大部分问题都得到了我接受的答案。
  • 我只举了 9 个不正确的例子(直到你最近终于接受了一些答案)。我真的不介意,但这让你看起来像是一个只对从社区中获取而不回馈感兴趣的人。此外,您的示例并不能真正代表问题(或者恕我直言,可能解释不清)。
  • 你能给出一个更明确的例子来说明你想要的输入/输出是什么样的吗?您可以使用slotNamesslotlapplymapply 来遍历 S4 对象中的插槽 ...
  • @BenBolker 我不想用 lapply 或任何循环进行迭代,我想问一下 list1 %in% list2 是否像上面那样。但是您应该建议列表包含 S4 对象。所以我的问题是,如果声明 list1 %in% list2 比较对象,我是否会通过相同的方式进行比较。

标签: r s4


【解决方案1】:

如果您想比较 S4 对象,我相信您将不得不使用(如 Ben Bolker 建议的)函数 slotNamesslotsapply 的混合。

setClass("MyClass",representation(Slot1="vector",Slot2="vector"))
x <- new("MyClass")
x@Slot1 <- 1:4
x@Slot2 <- LETTERS[1:4]
y <- new("MyClass")
y@Slot1 <- 1:4
y@Slot2 <- LETTERS[4:6]

id <- function(a,b){
        sapply(slotNames(a),function(x)identical(slot(a,x),slot(b,x)))
        }

id(x,y)
Slot1 Slot2 
 TRUE FALSE 

现在,如果您想将其扩展到 S4 对象列表,请在该 Metrics 解决方案之上使用:

X <- new("MyClass")
X@Slot1 <- 1:5
X@Slot2 <- LETTERS[1:4]
Y <- new("MyClass")
Y@Slot1 <- 1:4
Y@Slot2 <- letters[1:4]

a <- list(l1 = x, l2 = X)
b <- list(l1 = y, l2 = Y)

Map(id, a, b)
$l1
Slot1 Slot2 
 TRUE FALSE 

$l2
Slot1 Slot2 
FALSE FALSE 

【讨论】:

  • 我认为你也可以通过相同的方式比较整个对象,这样你就可以使用id &lt;- function(a,b){ sapply(a,function(x) any(Map(identical,x,b))) }
【解决方案2】:

您可以为此使用Map

Map(function (x,y) x %in% y, s, t)
$a
[1] TRUE TRUE TRUE

$b
[1]  TRUE FALSE FALSE

或者,正如@plannapus 所建议的,只需使用:

Map(`%in%`,s,t) 

【讨论】:

  • 我不清楚这就是 OP 想要的(尽管他们还没有成功地把它说得很清楚):我认为他们想要什么的类似物他们已经在上面显示了,但是对于带有插槽的 S4 类而不是带有元素的列表...
  • @BenBolker,你是对的。到目前为止,我按照我的描述进行操作,看看它是否会崩溃,因为我怀疑%in%identical 不同。
  • %in% 检查 x 的元素是否包含在 y 的元素中,而 identical 检查 x 和 y 是否相等且属于同一类。确实有不一样的。顺便说一句,您可以使用具有函数identical 的@Metrics 解决方案的变体:Map(identical,s,t)。如果您想在自己的 S4 类的插槽上使用 %in%identical,我相信您将必须定义自己的函数。
  • @plannapus,你说得对,如果想要我建议的解决方案,我必须使用 Map(identical,a,b)。有没有办法定义像 %in% 这样的运算符,它也适用于任意对象的列表。因为直到现在我还不太明白为什么我可以比较字符向量但不能比较 S4 对象。
【解决方案3】:

现在我定义了一个运算符,我这样做的方式是否正确?

"%inS4%" <- function(a,b) sapply(a,function(x) any(unlist(Map(identical,list(x),b))))
setClass(Class = "MyClass",
         representation = representation(name = "character",
                                         type = "character"
         )
)

a<-list(new("MyClass",name="abc",type="abc"),new("MyClass",name="abc",type="123"))
b<-list(new("MyClass",name="abc",type="123"),new("MyClass",name="abc",type="123"))

a %inS4% b

【讨论】:

  • @Metrics 是和否,类似,我的解决方案比较通用,我可以像在开始帖子中那样将对象列表与字符向量列表进行比较。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-14
  • 2014-10-08
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 2012-05-10
  • 1970-01-01
相关资源
最近更新 更多