2016-12-16 128 views
2

新的R,并在我的头!使用R中列间的成对计算创建矩阵R

我想编写的代码,将结合以下步骤:

a)求最小值,每行,两列

B)之和最小值之间找到

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

步骤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”相关的“功能”命令。但我很难过,可以真正使用一点帮助!

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

这是否有意义?

非常感谢。

回答

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而不是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)) 
+0

嗨亚伦,我用你的第一个建议,它效果很好!非常感谢你帮助我解决这个问题! – Monte

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

或AL ternatively(再次感谢阿伦),你可以做(​​和跳过最后一步)

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

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

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

    } 
+0

小心,lower.tri和上。三不是那样对称的。 – Aaron

+0

@Aaron抱歉,我没有得到,你能解释一下吗? – User2321

+1

添加第四列,并尝试它,你会看到所产生的基质是不是对称的,为R总是被列罢了。不过,这是一个很好的答案;我只是建议让你的内循环从1开始。 – Aaron