R 加权皮尔逊';s相关性?

R 加权皮尔逊';s相关性?,r,correlation,weighted,R,Correlation,Weighted,我有一个名为y的2396x34双矩阵,其中每行(2396)表示一个单独的情况,由34个连续的时间段组成 我还有一个名为x的numeric[34]表示34个连续时间段的单一情况 目前我正在计算y和x中每一行之间的相关性,如下所示: crs[,2]您可以返回到相关性的定义 f <- function( x, y, w = rep(1,length(x))) { stopifnot( length(x) == dim(y)[2] ) w <- w / sum(w) # Cent

我有一个名为
y
2396x34双矩阵
,其中每行(2396)表示一个单独的情况,由34个连续的时间段组成

我还有一个名为
x
numeric[34]
表示34个连续时间段的单一情况

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


crs[,2]您可以返回到相关性的定义

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)

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

vy <- rowSums( w * y * y )
是正确的,因为在这种情况下,乘法是按元素执行的,这相当于此处的按列乘法,但是

> 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)
}

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

这里是计算两个矩阵之间加权皮尔逊相关性的一个推广(而不是像原来的问题那样计算向量和矩阵):

就调用语法而言,这类似于未加权的
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
>a b矩阵.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

太棒了!成功了。再次感谢!我认为用R编写的函数会比内置在R中的函数慢很多。。。但我想不是吗?@vincentzoonekynd也许你应该看看这个并发表评论?我的答案中确实有一个bug(我想删除它,但无法删除已接受的答案)。当我用不正确的尺寸乘以对象时,我通常希望得到警告,但在这种情况下没有警告……我想之后最好添加一条注释,让您编辑您的答案,对此表示抱歉。至少现在这个bug已经被标记出来了,你仍然可以获得大部分工作的荣誉!
> 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)
}
> 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
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)) )
}
> sum(matrix.corr(as.matrix(x, nrow=34),t(y),xy.wt) - f2(x,y,xy.wt))
[1] 1.537507e-15
> 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