比较数字和整数值有时会返回TRUE,有时会返回FALSE。

4

我使用%in%来比较两个列表,一个包含数字值的向量,另一个包含相应的整数值。结果非常奇怪;有时是TRUE,有时是FALSE,我无法弄清原因。

例如下面的代码会返回TRUE

list(c(1, 1)) %in% list(c(1L, 1L))

然而,如果我们将向量中的第二个数字更改为2和2L,我们会得到FALSE

list(c(1, 2)) %in% list(c(1L, 2L))

将第二个数字更改为3或4再次返回TRUE
list(c(1, 3)) %in% list(c(1L, 3L))
list(c(1, 4)) %in% list(c(1L, 4L))

再使用其他值会再次产生FALSE,但我看不出任何模式。例如,使用8和9的结果是FALSE

list(c(8, 9)) %in% list(c(8L, 9L))

有人知道为什么会这样吗?这真的很让人困惑,我完全不知道它为什么会发生。

1个回答

7
这有点棘手。`%in%`是使用`match()`实现的(打印`%in%`显示`match(x, table, nomatch = 0L) > 0L`),而`?match`说: > 因子、原始向量和列表将转换为字符向量,然后进行比较。
现在让我们来比较一下:
- `as.character(list(c(1,1)))`是"c(1,1)"(整数等价物也是如此) - `as.character(list(c(1,2)))`是"c(1,2)" - 但是...`as.character(list(c(1L, 2L)))`是"1:2"!因为R识别连续的整数序列可以折叠成替代/紧凑表示形式(ALTREP)
(作为另一个例子,`as.character(list(7L, 8L, 9L))`是"7:9",而不是"c(7, 8, 9)")
作为解决方法,您可以使用as.numeric()显式地转换向量...
您还可以(如@user2554330所建议)向列表添加类属性(class(L) <- c("mylist", "list")),并定义一个mtfrm.mylist方法,以稍微更加有原则地进行强制转换到数值-字符之前的处理...

+10 分是因为您提供了 as.character 链接,我在研究中没有考虑到它。 - r2evans
2
将一个类添加到列表中,可以通过为该类定义“mtfrm”方法来更改比较方法。 - user2554330
哇,太棒了,这解释清楚了!谢谢。 as.numeric() 的解决方法有效。 - Honestiore
如果这个解决了您的问题/回答了您的问题,鼓励您点击对勾接受它。 - Ben Bolker

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