我有一个函数f(x,y),它返回一个包含8个逻辑向量的列表,其中x和y是整数。我想填充一个三维数组M,使得M [x,y,z]是f(x,y)的第z个元素中的TRUE数。我可以使用嵌套for循环来做到这一点,但我知道这些在R中是不受欢迎的。我认为使用outer
或rbind
和sapply
更优雅的方式我无法弄明白。这是我使用嵌套for循环的代码:
M <- array(dim=c(150, 200, 8))
for(j in 1:150) {
for(k in 1:200) {
rsu <- f(j, k)
for(z in 1:8) {
M[j, k, z] <- sum(rsu[[z]])
}}}
什么是更有效/更优雅的方式来填充此数组,从而得到相同的结果?
编辑添加:出于此问题的目的,请将f视为黑匣子。实际上,它涉及到关于八种不同卫星的各种计算和查找,但这里是一个虚拟函数,它将为此示例生成一些数据:
is.prime <- function(n) n == 2L || all(n %% 2L:ceiling(sqrt(n)) != 0)
#source for is.prime function:
# https://stackoverflow.com/questions/19767408/prime-number-function-in-r
f <- function(x,y) {
retlist <- list()
retlist[[1]] <- c(FALSE, FALSE, rep(TRUE, x))
retlist[[2]] <- c(TRUE, TRUE, rep(FALSE, y), rep(TRUE, y))
retlist[[3]] <- c(is.prime(x), is.prime(y), is.prime(x+y), is.prime(x+y+3), sapply(x:(2*(x+y)), is.prime))
retlist[[4]] <- c(x+y %% 5 == 0, x*y %% 6 ==0)
retlist[[5]] <- retlist[[(x+y) %% 4 + 1]]
retlist[[6]] <- retlist[[y %% 4 + 1]]
retlist[[7]] <- retlist[[x %% 6 + 1]]
retlist[[8]] <- sapply(abs(x-y):(7L*x+y+1), is.prime)
return(retlist)
}
答案 0 :(得分:0)
以下是如何填充数组,使用嵌套函数和sapply
代替以下内容给出相同的结果:
f2 <- function(x,y) {
rsu <- f(x,y)
values <- vapply(1:8, FUN=function(z) sum(rsu[[z]]), FUN.VALUE=1L)
}
f3 <- function(x) array(data=t(sapply(1:200, FUN=function(w) f2(x,w))), dim=c(1,200,8))
M2 <- array(data=t(sapply(1:150, FUN=f3)), dim=c(150,200,8))
答案 1 :(得分:0)
以下是outer
的使用方法。但它不直观;矩阵数据在函数内分配。我不明白为什么我需要在这里调用Vectorize(f2)
而不仅仅是f2
。
M2 <- array(dim=c(150, 200, 8))
f2 <- function(x, y) {
rsu <- f(x, y)
M2[x, y, ] <<- vapply(1:8, FUN=function(z) sum(rsu[[z]]), FUN.VALUE=1L)
return(0L)
}
ABC <- outer(1:150, 1:200, Vectorize(f2))