使用 R 中列之间的成对计算创建矩阵

Create matrix using pairwise calculations between columns in R

R 的新手,让我头疼!

我正在尝试编写结合以下步骤的代码:

a) 找出两列之间每行的最小值

b) 对找到的最小值求和

c) 在许多列中执行此操作并构建结果的成对矩阵

步骤 a 和 b 对于一次两列来说足够简单。像这样:

column1 = c(0.08,   0.20,   0.09,   0.19,   0.25,   0.20,   0.00)
column2 = c(0.07,   0.19,   0.09,   0.21,   0.25,   0.19,   0.00)
ps = data.frame(column1, column2)

sum(pmin(ps$column1,ps$column2))

但是对于步骤 c,我很难编写代码来对由 7 行和 32 列组成的数据帧中的每个成对列比较执行此操作。这是我到目前为止想出的:

d <- replicate(32, rnorm(7))
c <- combn(seq_len(ncol(d)),2)
mat1 <-  matrix(0,ncol=32,nrow=32,dimnames=list(colnames(d),colnames(d)))
v1 <- unlist(lapply(seq_len(ncol(c)),function(i) {d1<-d[,c[,i]];    length(which(d1[,1]!=0 & d1[,2]!=0)) }))

mat1[lower.tri(mat1)]<-v1 

我很确定我的问题出在与 "v1" 关联的 "function" 命令中。但我很难过,真的需要一点帮助!

同样,我的目标是在每个成对列比较之间获得一个 32x32 的求和最小值矩阵。

这有意义吗?

非常感谢。

我想你可以尝试以下方法(我不得不承认这是一种简单的方法):

column1 = c(0.08,   0.20,   0.09,   0.19,   0.25,   0.20,   0.00)
column2 = c(0.07,   0.19,   0.09,   0.21,   0.25,   0.19,   0.00)
column3 = c(0.05,   0.49,   0.39,   0.1,   0.5,   0.11,   0.01)
ps = data.frame(column1, column2, column3)

res <-matrix(nrow = ncol(ps), ncol = ncol(ps))

for (i in (1:ncol(ps))) {

  for (j in (i:ncol(ps))){

    res[i,j] <- sum(pmin(ps[,i],ps[,j]))
  }

}

为了利用矩阵对称的事实,你可以这样做:

res[lower.tri(res)] <- t(res)[lower.tri(res)]

(需要注意的一件事是,我也从@Aaron 那里了解到,他的评论是 res[lower.tri(res)] <- res[upper.tri(res)] 不起作用,因为 R 正在按列填充值)

或者(再次感谢亚伦)你可以这样做(并跳过最后一步):

for (i in (1:ncol(ps))) {

      for (j in (i:ncol(ps))){

        res[i,j] <- res[j,i] <- sum(pmin(ps[,i],ps[,j]))
      }

    }

outer 函数会执行此操作并为您跟踪簿记,但您必须向其传递矢量化函数。

summin <- Vectorize(function(i, j) sum(pmin(ps[[i]], ps[[j]])))
outer(seq_len(ncol(ps)), seq_len(ncol(ps)), FUN=summin)
##      [,1] [,2]
## [1,] 1.01 0.98
## [2,] 0.98 1.00

我不知道你的 v1 代码中应该发生什么,看起来你不再对最小值求和了。

如果我要循环自己,我会使用 expand.grid 而不是 combn,因为这样我就得到了对角线,而不必弄清楚如何填充矩阵的两侧,尽管以两次执行所有计算为代价。 (无论如何,计算机可以比我弄清楚如何让它只做一次快两倍。)我也只是把它作为一个向量,然后再转换成一个矩阵。

cc <- expand.grid(seq_len(ncol(d)), seq_len(ncol(d)))
out <- sapply(seq_len(nrow(cc)), function(k) {
    i <- cc[k,1]
    j <- cc[k,2]
    sum(pmin(d[[i]],d[[j]]))
})
out <- matrix(out, ncol=ncol(d))