像dist / rdist这样的函数是否存在处理NA的函数?

问题描述 投票:1回答:2

我正在使用来自rdist包的fields函数,但现在我想在我的矩阵中处理​​NA,就像dist函数那样。

有这样的功能吗?

一种解决方案是直接使用dist,但我的矩阵有超过150K行,所以这不是一个选项。

编辑:注意比用complete.casesna.omit删除行或列不是我正在寻找的解决方案。帮助dist函数中描述了预期的行为:

允许缺少值,并且从涉及它们发生的行的所有计算中排除这些值。此外,当涉及Inf值时,当它们对距离的贡献给出NaN或NA时,排除所有值对。如果在计算欧几里德,曼哈顿,堪培拉或闵可夫斯基距离时排除某些列,则总和将按比例缩放到所使用的列数。如果在计算特定距离时排除所有对,则该值为NA。

我添加了一个示例代码来说明这一点。鉴于此向量:

vx <- matrix(c(1,2,3), nrow=1)
vy <- matrix(c(2,7,10), nrow=1)
vy.na <- matrix(c(2,NA,10), nrow=1)

dist计算忽略第二列的距离并扩展到3列,所以

dist(rbind(vx,vy))
dist(rbind(vx,vy.na))
rdist(vx,vy)

所有返回相同=> 8.660254

rdist(vx,na.omit(vy.na))

不返回任何距离值,因为na.omit省略了整行。

另一方面,通过成对的矢量单独计算距离比qazxsw poi慢一些。

我的替代解决方案是用“中性”值填充NA(如该列的中位数),但我更喜欢rdist行为。

r packages distance na
2个回答
2
投票

编辑

看完这篇文章dist后,我觉得看起来真的没有让dist handling na's来处理NA值。此外,该帖子还介绍了rdist如何补偿删除缺失值。

使用此信息,我编写了以下脚本。

dist

全部返回8.660254其中:

rdist.alt <- function (x1, x2, na.rm=TRUE) 
    {
    lx <- length(x1)
      if (missing(x2)) 
            x2 <- x1
    if (!as.matrix(x1))
        x1 <- as.matrix(x1)
    if (class(x2) == "matrix")
        x2 <- as.vector(x2)
    if (na.rm)
        na.id <- is.na(x1) | is.na(x2)
        x1 <- x1[!na.id]
        x2 <- x2[!na.id]
        lxa <- length(x1)
    eucd <- sqrt(sum((x1 - x2)^2) * lx/lxa)
    return(eucd)
    }

dist(rbind(vx,vy))
dist(rbind(vx,vy.na))
rdist(vx,vy)
rdist.alt(vx,vy)
rdist.alt(vx,vy.na)

因为rdist(vx,vy.na) Error in rdist(vx, vy.na) : NA/NaN/Inf in foreign function call (arg 4) 不处理缺失值。

但是,如果你想输入一个矩阵并期望从rdist得到这样的输出

dist

您将不得不修改上面的脚本。希望这可以帮助。

---------原帖-----------------

在将矩阵传递给 dist(xy) 1 2 3 4 5 6 7 8 9 2 1.9305914 3 2.2242914 2.8088390 4 3.1357792 2.1320489 2.1348279 5 1.1663478 1.1691107 2.5429175 0.1244745 6 5.0549708 4.1017549 3.4565211 2.0071521 0.1149399 7 6.2926407 5.0060108 4.9231242 3.1572273 1.5159374 1.5263946 8 7.3670783 6.0345762 5.9742805 4.2325789 2.0813721 2.5321716 1.0769671 9 8.0027390 7.1469945 6.1154624 5.0492331 0.8702670 3.0471724 2.6166746 2.3143221 10 9.0061376 8.1080028 7.1207560 6.0279981 0.6962094 4.0210617 3.3833115 2.8031196 1.0075455 函数之前,您始终可以在矩阵上调用na.omit

EG

rdist

或者,如果您不关心保留NA值

xy <- structure(list(x = c(1L, 2L, 3L, 4L, NA, 6L, 7L, 8L, 9L, 10L), y = c(-1.07436356530045, 0.577054958924021, -2.0477453543004, -0.161614353806037, -0.249631114549562, -0.33090588210086, 0.822298505061525, 1.22212120980467, -0.865002838232734, -0.741925512264102)), .Names = c("x", "y"), row.names = c(NA, -10L), class = "data.frame")

xy2 <- na.omit(xy)
rdist(xy2)

1
投票

在阅读了@deHaas的答案和他的评论之后,我可以写一个有效版本的xy <- na.omit(xy) rdist(xy) 来处理NAs为rdist

dist

特别是library(pdist) rdist.w.na <- function(X,Y) { if (!is.matrix(X)) X = as.matrix(X) if (!is.matrix(Y)) Y = as.matrix(Y) distances <- matrix(pdist(X,Y)@dist, ncol=nrow(X), byrow = TRUE) #count NAs na.count <- sapply(1:nrow(X),function(i){rowSums(is.na(Y) | is.na(X[i,]))}) #scaling to number of cols distances * sqrt(ncol(X)/(ncol(X) - na.count)) } 相当于rdist.w.na(X,X),但它返回一个完整的对称矩阵而不是下三角形矩阵。

© www.soinside.com 2019 - 2024. All rights reserved.