我正在使用来自rdist
包的fields
函数,但现在我想在我的矩阵中处理NA,就像dist
函数那样。
有这样的功能吗?
一种解决方案是直接使用dist
,但我的矩阵有超过150K行,所以这不是一个选项。
编辑:注意比用complete.cases
或na.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
行为。
编辑
看完这篇文章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)
在阅读了@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)
,但它返回一个完整的对称矩阵而不是下三角形矩阵。