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

时间:2016-12-16 22:19:47

标签: r matrix multiple-columns

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矩阵。

这有意义吗?

非常感谢你。

2 个答案:

答案 0 :(得分:2)

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而不是梳理,因为我得到了对角线,并且不必弄清楚如何填充对角线矩阵,但代价是两次完成所有计算。 (无论如何,计算机的速度可以比我弄清楚如何让它只做一次。)我也只是把它作为矢量然后转换成矩阵。

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

答案 1 :(得分:1)

我认为您可以尝试以下方法(这是一种我必须承认的简单方法):

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按列填充值)

或者(再次感谢Aaron)你可以做(​​并跳过最后一步):

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

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

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

    }