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