计算R中两个向量的汉明距离?

计算R中两个向量的汉明距离?,r,R,我只是试图计算R中两个向量之间的汉明距离。我目前正试图使用“e1071”包和Hamming.distance函数,如下所示: library(e1071) H <- hamming.distance(X) 经过一些研究,似乎有一个修复方法可能是增加R中的基本选项。我通过选项(表达式=5000)进行了此操作,然后尝试改变值来代替5000。但这只会产生错误: Error: evaluation nested too deeply: infinite recursion / options(

我只是试图计算R中两个向量之间的汉明距离。我目前正试图使用“e1071”包和Hamming.distance函数,如下所示:

library(e1071)
H <- hamming.distance(X) 
经过一些研究,似乎有一个修复方法可能是增加R中的基本选项。我通过选项(表达式=5000)进行了此操作,然后尝试改变值来代替5000。但这只会产生错误:

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?
Error: C stack usage is too close to the limit
我不是一个程序员,最近这个错误的修复似乎与包e1071中的某些内容有关,可能没有正确调用(或在正确的时间调用)


你知道我做错了什么吗?我最终想要大量向量之间的汉明距离,这只是一个起点。如果这与内存分配有关,有没有关于如何处理的建议

我不知道
hamming.distance
在内部是如何工作的,但是计算两个向量的距离的简单方法是

sum(x1 != x2)
或者,在这种情况下

sum(X[1,] != X[2,])
如果向量的总数不太大(比如说,多达几千个),您可以在嵌套循环中实现这一点:

n <- nrow(X)
m <- matrix(nrow=n, ncol=n)
for(i in seq_len(n - 1))
    for(j in seq(i, n))
        m[j, i] <- m[i, j] <- sum(X[i,] != X[j,])

n
hamming.distance
采用两个向量或一个矩阵,但不是一个数据帧,因此您可能需要的是

m = as.matrix(X)
hamming.distance(m[1,], m[2,])

但正如所指出的,在你的特殊情况下,这与

sum(m[1,] != m[2,])
(通常,如果您拥有的不是异构结构,则避免使用
data.frame
s,因为它们比矩阵慢得多)


我不知道“异或”对“!=”的相对效率

关于使用HAMMING的警告。与e1071包的距离

此包的实现强制将对象与带有as.logical的布尔值进行比较。这意味着0的值将为FALSE,任何非零值都将为TRUE。这意味着对于序列:0 1 2与0 1 1相比,汉明距离将报告为0,而不是正确的值1——此包将视1和2为相等,因为as.logical(1)=as.logical(2)

以下是错误的(在我看来)实现:

    > library("e1071", lib.loc="C:/Program Files/R/R-2.15.3/library")
    Loading required package: class
    > hamming.distance
    function (x, y) 
    {
        z <- NULL
        if (is.vector(x) && is.vector(y)) {
            z <- sum(as.logical(x) != as.logical(y))
        }
        else {
            z <- matrix(0, nrow = nrow(x), ncol = nrow(x))
            for (k in 1:(nrow(x) - 1)) {
                for (l in (k + 1):nrow(x)) {
                    z[k, l] <- hamming.distance(x[k, ], x[l, ])
                    z[l, k] <- z[k, l]
                }
            }
            dimnames(z) <- list(dimnames(x)[[1]], dimnames(x)[[1]])
        }
        z
    }
    <environment: namespace:e1071>
>库(“e1071”,lib.loc=“C:/Program Files/R/R-2.15.3/library”)
加载所需的包:类
>汉明距离
函数(x,y)
{
z只是添加到@HongOoi中,我想指出,在R
!=
=
中,当其中一个值丢失时,返回
NA
,因此它可能会给出误导性的结果

> c(1, NA) == 1:2
[1] TRUE   NA
但是,
%in%
为%NA
比较中的
1%输出
FALSE
。因此,如果在比较向量时希望将缺少的值计算为“不同”,则必须使用
求和(!((x!=y)%in%FALSE))
代码:

> x <- c(1, 8, 5, NA, 5)
> y <- 1:5
> sum(!((x != y) %in% FALSE))
[1] 3

此函数允许您选择是否将缺少的值计算为“不同”(
na.rm=FALSE
)或者忽略它们。使用
na.rm=TRUE
如果向量的长度不同,那么越长的向量就会被截断。

作为上述所有内容的补充:尽管汉明距离作为普通嵌套循环实现起来微不足道,但就执行时间而言,对于较大的矩阵,事情可能会很快失控。在R中,这远远不够使用矩阵乘法计算大型矩阵所有列之间的汉明距离更有效。与R级嵌套循环相比,这是非常快的。可以找到一个示例实现。

这不是真正的内存问题,而是堆栈问题:函数是递归的,调用自身的次数与你有列。你可能想检查是否有其他非递归实现(例如,通过键入
库(sos);??hamming
),或者实现你自己的。此外,我无法重现问题(
表达式对我来说已经是5000):关于你平台的信息(例如
会话信息()
)可能会有帮助。太棒了!你们帮了大忙。这太棒了。小心NA测试。谢谢你们的注释。我最终只是用Hong Ooi提到的非常简单的方法计算了它。但总的来说,这很好。我继续向包维护人员发送了一封关于这个问题的电子邮件。
xor
是实现的d作为
函数(x,y){(x | y)&!(x&y)}
!=
是一个原始函数。我怀疑
!=
更有效。
> c(1, NA) == 1:2
[1] TRUE   NA
> x <- c(1, 8, 5, NA, 5)
> y <- 1:5
> sum(!((x != y) %in% FALSE))
[1] 3
hamming <- function(x, y, na.rm = TRUE) {
  size <- 1:max(length(x) & length(y))
  x <- x[size]
  y <- y[size]
  if (na.rm) {
    del <- is.na(x) & is.na(y)
    x <- x[del]
    y <- y[del]
  }
  sum(!((x != y) %in% FALSE))
}