R:从列表

时间:2017-09-22 07:32:58

标签: r nested-loops

我有一个函数f(x,y),它返回一个包含8个逻辑向量的列表,其中x和y是整数。我想填充一个三维数组M,使得M [x,y,z]是f(x,y)的第z个元素中的TRUE数。我可以使用嵌套for循环来做到这一点,但我知道这些在R中是不受欢迎的。我认为使用outerrbindsapply更优雅的方式我无法弄明白。这是我使用嵌套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)
}

2 个答案:

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