R中使用apply函数的列表对象之间的操作



我在R中有一个1x5矩阵A和一个包含矩阵(double [100x100])的5个B列表。A的每个参数对应一个B,我想创建以下函数

C = ( max(A[,i],A[,j]) * B[[i]] * B[[j]] ) / 2

例如,要计算1和2之间的C,我可以使用下面的
set.seed(123)
A <- matrix(c(5.2,6.9,32,40,8.3), ncol = 5 )
B <- list(matrix(rnorm(100 * 100, mean = 0, sd = 1), 100, 100), 
matrix(rnorm(100 * 100, mean = 0, sd = 1), 100, 100), 
matrix(rnorm(100 * 100, mean = 0, sd = 1), 100, 100), 
matrix(rnorm(100 * 100, mean = 0, sd = 1), 100, 100), 
matrix(rnorm(100 * 100, mean = 0, sd = 1), 100, 100))
C_1.2<- max(A[,1],A[,2]) * (unlist(B[[1]])*unlist(B[[2]]))

我想在R中创建一个列表,该列表用于使用apply函数的所有可能组合?我希望名字是C_j.j。我设法这样做:

combinations <- combn(1:5, 2)
result_list <- lapply(1:ncol(combinations), function(i){
j <- combinations[1, i]
k <- combinations[2, i]

C <- (max(A[, j], A[, k]) * B[[j]] * B[[k]]) / 2

list(C)
})
names(result_list) <- paste0("C_", combinations[1, ], ".", combinations[2, ])

但是我不能生产C_1.1,C_2.2,C_3.3,C_4.4,C_5.5。我怎样才能解决这个问题呢?我想当I =j时,然后计算C_i.i <- (A[,i] * B[[i]]^2) / 2

基于答案的解决方案是

out2 <- apply(expand.grid(seq_along(B), seq_along(B)), 1, (i) 
(max(A[, i]) * (B[[i[1]]] * B[[i[2]]])), simplify = FALSE)
names(out2) <- paste0("C_", do.call(paste, 
c(expand.grid(seq_along(B), seq_along(B)), sep = ".")))

C <- lapply(1:5, function(i) {
lapply(1:5, function(j) {
if (i == j) {
C_i.i <- (A[,i] * B[[i]]^2)
} else {
C_i.j <- max(A[,i],A[,j]) * (unlist(B[[i]])*unlist(B[[j]]))
}
})
})

,然而,它创建了所有可能的场景,并使计算时间翻倍,因为我们知道C_1.2 = C_2.1和吨计算是需要的。

我们可以直接在combn

out <- combn(seq_along(B), 2, FUN = function(i) 
(max(A[, i]) * (B[[i[1]]] * B[[i[2]]])), simplify = FALSE)
names(out) <- paste0("C_", combn(seq_along(B), 2, FUN = paste, collapse = "."))

-用OP的输出

检查输出
> C_1.2<- max(A[,1],A[,2]) * (unlist(B[[1]])*unlist(B[[2]]))
> all.equal(out[[1]], C_1.2)
[1] TRUE

如果我们想要所有的组合,使用expand.grid

out2 <- apply(expand.grid(seq_along(B), seq_along(B)), 1, (i) 
(max(A[, i]) * (B[[i[1]]] * B[[i[2]]])), simplify = FALSE)
names(out2) <- paste0("C_", do.call(paste, 
c(expand.grid(seq_along(B), seq_along(B)), sep = ".")))

最新更新