英文:
Comparing numeric and integer values sometimes gives TRUE and sometimes FALSE
问题
我使用 %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))
有人知道为什么会这样吗?这真的令人困惑,我完全不明白为什么会发生这种情况。
英文:
I use %in%
to compare two lists, one with a vector of numeric values and the other with corresponding integer values. The result is really weird; sometimes TRUE
and sometimes FALSE
and I can't figure out why.
For example the code below gives TRUE
list(c(1, 1)) %in% list(c(1L, 1L))
However, if we change the second number in the vectors to 2 and 2L we get FALSE
list(c(1, 2)) %in% list(c(1L, 2L))
Changing the second number to 3 or 4 gives TRUE
again.
list(c(1, 3)) %in% list(c(1L, 3L))
list(c(1, 4)) %in% list(c(1L, 4L))
Using some other values again produces FALSE
but I can't see any pattern to this. For example using 8 and 9 results in FALSE
:
list(c(8, 9)) %in% list(c(8L, 9L))
Does anyone know why this is the case? It's really baffling and I'm completely lost why it's happening.
答案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
方法,以稍微更有原则的方式执行强制转换为数字然后再转换为字符的操作...
英文:
This is a bit tricky. %in%
is implemented using match()
(printing `%in%`
shows match(x, table, nomatch = 0L) > 0L
), and ?match
says
> Factors, raw vectors and lists are converted to character vectors
before comparison. Now let's compare:
as.character(list(c(1,1)))
is "c(1,1)" (and the same for the integer equivalent)as.character(list(c(1,2)))
is "c(1,2)"- but ...
as.character(list(c(1L, 2L)))
is "1:2" (!), because R recognizes a contiguous integer sequence as one that can be collapsed to an alternative/compact representation (ALTREP)
(As another example, as.character(list(7L, 8L, 9L))
is "7:9", not "c(7, 8, 9)")
As a workaround, you could explicitly convert the vectors with as.numeric()
...
You could also (as suggested by @user2554330) add a class attribute to your lists (class(L) <- c("mylist", "list")
) and define a mtfrm.mylist
method to do the coercion-to-numeric-before-character stuff in a slightly more principled way ...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论