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矩阵。
这有意义吗?
非常感谢你。
答案 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]))
}
}