如何获取两个R命名列表之间的差异?

18

好的,我有两个命名列表,一个是"expected",另一个是"observed"。它们的结构可能非常复杂,包含任意数据类型。我想获取一个新的列表,只包含观察列表中与期望列表不同的元素。以下是一个例子:

Lexp <- list(a=1, b="two", c=list(3, "four"))
Lobs <- list(a=1, c=list(3, "four"), b="ni")
Lwant <- list(b="ni")

Lwant是我希望得到的结果。我尝试了这个:

> setdiff(Lobs, Lexp)
[[1]]
[1] "ni"

不行,那会丢失名称,而我认为setdiff不会注意名称。 显然这里顺序无关紧要,我不希望a=1b=1匹配。

不确定好的方法是什么...循环遍历名称(Lobs)列表?听起来笨拙且不像R风格,但可行...有什么优雅的想法吗?

2个回答

35

至少在这种情况下,

Lobs[!(Lobs %in% Lexp)]

可以给你想要的结果。


我昨天刚用过%in%函数进行调试,准备推荐它。 - JD Long
顺便提一句,这是正确的,但原因不正确。名称未被使用,只使用了值。例如,如果我们将第一个列表重命名为Lexp <- list(a=1, d="ni", c=list(3, "four")),那么此答案返回意外的空命名列表,而应该是list(b = "ni") - eliot.mcintire

0

好的,我发现了一个略微晦涩的答案,使用 plyr 包:

> Lobs[laply(names(Lobs), function(x) !identical(Lobs[[x]], Lexp[[x]]))]
$b
[1] "ni"

因此,它从观察函数中获取数组的名称,使用双括号索引和identical()函数来比较子列表,然后使用由laply()产生的二进制数组来索引原始观察函数。

有人有更好/更清洁/更性感/更快的方法吗?


1
你不需要 plyr:Lobs[sapply(names(Lobs), function(x) !identical(Lobs[[x]], Lexp[[x]]))] - Marek
@Harlan - 两个具有相同结构的列表之间是否可能找到百分比差异?我正在尝试比较预期结果与观察结果之间的差异有多大? - Chetan Arvind Patil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接