加权皮尔逊的相关性?

时间:2012-02-27 06:00:46

标签: r correlation weighted

我有一个名为2396x34 double matrix的{​​{1}},其中每一行(2396)代表一个由34个连续时间段组成的单独情况。

我还有一个名为y的{​​{1}}代表连续34个时段的单一情况。

目前我正在计算numeric[34]x中每一行之间的相关性,如下所示:

y

我现在需要的是用加权相关替换上述语句中的x函数。权重向量crs[,2] <- cor(t(y),x)长度为34个元素,因此可以为34个连续时间段中的每一个分配不同的权重。

我找到cor函数cov.wt,并认为如果我首先xy.wt数据,它应该像Weighted Covariance Matrix函数一样工作。实际上,您也可以为函数指定返回相关矩阵。不幸的是,似乎我不能以相同的方式使用它,因为我无法单独提供我的两个变量(scalecor)。

有没有人知道我可以在不牺牲太多速度的情况下以我描述的方式获得加权相关的方法?

编辑:也许某些数学函数可以在x函数之前应用于y,以便获得我正在寻找的相同结果。也许如果我将每个元素乘以y

编辑#2 我在cor包中找到了另一个函数corr

xy.wt/sum(xy.wt)

这也不是我需要的,但它更接近。

编辑#3 以下是生成我正在使用的数据类型的一些代码:

boot

3 个答案:

答案 0 :(得分:23)

不幸的是,当y是多行的矩阵时,接受的答案是错误的。错误在行

vy <- rowSums( w * y * y )

我们希望将y的列乘以w,但这会将行乘以w的元素,并根据需要进行回收。因此

> f(x, y[1, , drop = FALSE], xy.wt)
[1] 0.103021

是正确的,因为在这种情况下,乘法是按元素执行的,这相当于此处的逐列乘法,但是

> f(x, y, xy.wt)[1]
[1] 0.05463575
由于行方式的乘法,

给出了错误的答案。

我们可以按如下方式更正功能

f2 <- function( x, y, w = rep(1,length(x))) {
  stopifnot(length(x) == dim(y)[2] )
  w <- w / sum(w)
  # Center x and y, using the weighted means
  x <- x - sum(x * w)
  ty <- t(y - colSums(t(y) * w))
  # Compute the variance
  vx <- sum(w * x * x)
  vy <- colSums(w * ty * ty)
  # Compute the covariance
  vxy <- colSums(ty * x * w)
  # Compute the correlation
  vxy / sqrt(vx * vy)
}

并根据corr包中的boot生成的结果检查结果:

> res1 <- f2(x, y, xy.wt)
> res2 <- sapply(1:nrow(y), 
+                function(i, x, y, w) corr(cbind(x, y[i,]), w = w),
+                x = x, y = y, w = xy.wt)
> all.equal(res1, res2)
[1] TRUE

这本身就提供了解决这个问题的另一种方式。

答案 1 :(得分:3)

您可以回到相关性的定义。

f <- function( x, y, w = rep(1,length(x))) {
  stopifnot( length(x) == dim(y)[2] )
  w <- w / sum(w)
  # Center x and y, using the weighted means
  x <- x - sum(x*w)
  y <- y - apply( t(y) * w, 2, sum )
  # Compute the variance
  vx <- sum( w * x * x )
  vy <- rowSums( w * y * y ) # Incorrect: see Heather's remark, in the other answer
  # Compute the covariance
  vxy <- colSums( t(y) * x * w )
  # Compute the correlation
  vxy / sqrt(vx * vy)
}
f(x,y)[1]
cor(x,y[1,]) # Identical
f(x, y, xy.wt)

答案 2 :(得分:3)

这是计算两个矩阵之间的加权Pearson相关性的概括(而不是像原始问题那样的向量和矩阵):

matrix.corr <- function (a, b, w = rep(1, nrow(a))/nrow(a)) 
{
    # normalize weights
    w <- w / sum(w)

    # center matrices
    a <- sweep(a, 2, colSums(a * w))
    b <- sweep(b, 2, colSums(b * w))

    # compute weighted correlation
    t(w*a) %*% b / sqrt( colSums(w * a**2) %*% t(colSums(w * b**2)) )
}

使用上面的例子和Heather的相关函数,我们可以验证它:

> sum(matrix.corr(as.matrix(x, nrow=34),t(y),xy.wt) - f2(x,y,xy.wt))
[1] 1.537507e-15

在调用语法方面,这类似于未加权的cor

> a <- matrix( c(1,2,3,1,3,2), nrow=3)
> b <- matrix( c(2,3,1,1,7,3,5,2,8,1,10,12), nrow=3)
> matrix.corr(a,b)
     [,1]      [,2] [,3]      [,4]
[1,] -0.5 0.3273268  0.5 0.9386522
[2,]  0.5 0.9819805 -0.5 0.7679882
> cor(a, b)
     [,1]      [,2] [,3]      [,4]
[1,] -0.5 0.3273268  0.5 0.9386522
[2,]  0.5 0.9819805 -0.5 0.7679882