R中Cor()的结果没有按照我的预期进行逻辑评估

时间:2013-05-20 16:52:05

标签: r logic correlation

我试图找到一种好方法来测试两个向量之间的相关性是否完美(或NA)。我尝试了很多不同的方法,但是我遇到了类似的问题,即相关的结果不会以我期望的方式评估。

这是我最新的例子:

foo1 <- c(4, NA, 6, NA)   
foo2 <- c(1, 2, 3, 4)
set  <- c(-1, 1, NA)
correlation <- cor(foo1, foo2, use = "na.or.complete")  # Result: 1
correlation %in% set  # Should be TRUE, is FALSE
correlation == 1      # Should also be TRUE, but is FALSE

is.numeric(correlation)为TRUE。我能在其中或周围看到的唯一价值是1.那么为什么世界上这不起作用?

set  <- c('-1', '1', NA)

这有效,但我不确定为什么,而且我担心有些方法可能会失败,因为我显然不明白返回值会发生什么。

任何见解都会有所帮助!

3 个答案:

答案 0 :(得分:2)

相反,您可以确保它们与您的集合足够接近:

mytol <- 1e-10
set <- set[1:2]
any(abs(correlation - set) <= mytol)|is.na(correlation) # TRUE

我想,它与浮子和公差有关。我不确定标准参考是什么,但这里有一个:Numeric comparison difficulty in R

1不是真的1;如果你想要一个整数(这里我猜你不应该),你可以使用1L。像1:3seq(1,3)这样创建的向量也是整数。有关详细信息,请查看?integer?numeric。奇怪的是,我找不到涵盖各类之间差异的文档页面。

编辑:我将支票拆分为NA,因为OP指出,它不起作用。

答案 1 :(得分:2)

我认为这基本上是常见问题7.31,但“如何查看某个值是否在一个集合内(在容差范围内)”需要略微扩展标准“只使用all.equal()”答案...... < / p>

test <- function(x) {
          isTRUE(all.equal(x,-1)) || 
            isTRUE(all.equal(x,1)) || is.na(x)
}
test(1-1e-14)  ## TRUE
test(NA)       ## TRUE
test(0.88)      ## FALSE

是您问题的最精确解决方案,但我可以看到,如果你有更长的候选人名单会很困难......因为isTRUE(all.equal(1,NA))FALSE(方便)也许

test <- function(x,candidates=c(-1,1,NA), ...) {
    any(sapply(lapply(candidates,all.equal,target=x,...),
               isTRUE))
}
test(1-1e-6)    ## FALSE
test(1-1e-6,tolerance=1e-4)  ## TRUE

这里的一个问题是,isTRUE(all.equal(NA,NaN)) TRUE,因此可能需要构建is.na()(对NA进行测试或者NaN)在这里的某个地方,或者在候选人名单中加入NaN

答案 2 :(得分:1)

你们的人非常乐于助人。对于感兴趣的人来说,这是最终的结果,尽管我显然必须更多地考虑我的容差。

corrIsOkay <- function(x, y){
  correlation  <- cor(x, y, use = "na.or.complete")
  if ((1 - abs(correlation)) <= .01 | is.na(correlation)){
    print(correlation)
    return(FALSE)
  }
  return(TRUE) 
}

这比我想要的要多得多,因为我原来的“解决方案”本身适合if语句,但现在我只是在if语句中调用这个函数。

makeMvMissing <- function(data) {
  repeat {
      x <- makeMissing(data)[, 1]
      y <- makeMissing(data, variable.missing = "y")[, 2]
      if (corrIsOkay(x, y)){
        break
      }
    }
  return(data.frame(x, y))
}