1

我有以下功能,当放在第一个示例中时可以正常工作。但是,我希望其中两个变量在 mapply 函数中分别具有另外两个列表,以便以任何形式提供两个结果。变量 w2 是一个包含两个组件的列表,而 xx 是一个包含 2 个向量的列表。

library(wmtsa)

# data feed to function
wavelet <-  c("d2","s2","d4","s4","d6")
schrinkfun <- c("soft","hard") 
threshfun <- c("universal", "adaptive")
threshscale <- c(0.05,0.1,0.15,0.2)
xx <- c(1,2,3,4,5,6,7,5,4,3,2,4,3,2,3,5,4,3,2,3,4,5,6,3,2,1,2,3,5,4,3,3)
nlevel<-seq(1: as.integer (floor (logb ((length(xx)),base=2))))   
w2 <- expand.grid(wavelet=wavelet,nlevel=nlevel,schrinkfun=schrinkfun, threshfun= threshfun, threshscale= threshscale, stringsAsFactors=FALSE) 

# Original function: To which I apply a unique list of values (w2) and a single vector for x. This function works fine.  

result <-  mapply(function(m,k,p,u,l,x)  (wavShrink(x, wavelet= m, n.level =k, shrink.fun = p, thresh.fun =u, threshold=NULL, thresh.scale = l, xform="modwt", noise.variance=-1, reflect=TRUE)), w2$wavelet, w2$nlevel, w2$schrinkfun, w2$threshfun, w2$threshscale, MoreArgs=list(x=(xx)))

# Attempt to use (1) the index of w2 which is now a list of two (index z) - (2) the index of the list of xx which is a list of tow (index g). Again data feed with new levels and xx now formed each by a list of two elements. 

wavelet <-  c("d2","s2","d4","s4","d6")
schrinkfun <- c("soft","hard") 
threshfun <- c("universal", "adaptive")
threshscale <- c(0.05,0.1,0.15,0.2)
xx <- list(c(1,2,3,4,5,6,7,5,4,3,2,4,3,2,3,5,4,3,2,3,4,5,6,3,2,1,2,3,5,4,3,3),c(0,3,1,4,1,2,7,5,4,1,3,4,9,2,7,5,1,3,2,2,4,7,6,4,2,1,1,1,5,1,3,1))
g <- seq(1:length(xx))
fun <- function (x) seq(1: as.integer (floor (logb ((length(xx[[x]])),base=2))))   
nlevel <- lapply( g,fun)
fun <-  function(x) expand.grid(wavelet=wavelet,nlevel=nlevel[[x]], schrinkfun=schrinkfun, threshfun= threshfun, threshscale= threshscale, stringsAsFactors=FALSE) 
w2 <- lapply(g,fun)
z <- seq(1:length(w2))

# Attempt 1  
result <-  mapply(function(m,k,p,u,l,x)  (wavShrink(x, wavelet= m, n.level =k, shrink.fun = p, thresh.fun =u, threshold=NULL, thresh.scale = l, xform="modwt", noise.variance=-1, reflect=TRUE)), w2[[z]]$wavelet, w2[[z]]$nlevel, w2[[z]]$schrinkfun, w2[[z]]$threshfun, w2[[z]]$threshscale, MoreArgs=list(x=(xx[[g]])))
Error in w2[[z]]$wavelet : $ operator is invalid for atomic vectors

# Attempt 2  
result <-  mapply ( function(z,g) ( mapply ( function(m,k,p,u,l,x)  (wavShrink(x, wavelet= m, n.level =k, shrink.fun = p, thresh.fun =u, threshold=NULL, thresh.scale = l, xform="modwt", noise.variance=-1, reflect=TRUE)), w2[[z]]$wavelet, w2[[z]]$nlevel, w2[[z]]$schrinkfun, w2[[z]]$threshfun, w2[[z]]$threshscale, MoreArgs=list(x=(xx[[g]])))))
result
list()

我可能没有正确使用第二个 mapply,因为它似乎不起作用。我想知道这是否可以被表述为最后一个 mapply 的循环,其中两个变量应该输入到 mapply 函数中,或者我可以使用另一个 apply 系列来执行此操作。结果应该与在单独的变量数据馈送中两次应用正确的第一个示例相同,但作为列表加入。

编辑

Following the reponse from frank. A question that has promted is how would you reformulate the expression response function if MoreArgs=list ( x = ( xx[[i]][[1]] )) was -- MoreArgs=list(x=(xx[[ i ]][[ j ]]))), meaning a new variable would have been introduced into the function - j - which is not included in any of the parts as per adding this to your solution above.

4

1 回答 1

1

Not being sure about the problem you're trying to solve all I can say about the result of the code below is that it runs and that the answer is consistent with the result obtained from your first attempt.

I created a function called mapply2, shown below.

mapply2 <- function(i){
    w3 <- w2[[i]]
    mapply(function(m,k,p,u,l,x) wavShrink(x, wavelet= m, n.level =k, shrink.fun = p, 
                                          thresh.fun =u, threshold=NULL, 
                                          thresh.scale = l, xform="modwt", 
                                          noise.variance=-1, reflect=TRUE), 
          w3$wavelet, w3$nlevel, w3$schrinkfun, w3$threshfun, 
          w3$threshscale, MoreArgs=list(x=(xx[[i]])))
}

Note that I indexed the list xx by the same variable as the rest of the input, purely because w2 and xx were lists of the same length. (is this acceptable?)

The function is then called for each w2 and xx by using lapply,

result <- lapply(z, mapply2)

Also note that the function input (or lack there of) requires that mapply2 is called from the same environment that contains w2 and xx.

Edit: Without having access to the full example I can only take a guess about how to modify my answer. But my best guess is that something along the lines of

mapply2 <- function(xxi, w){

    mapply(function(m,k,p,u,l,x) wavShrink(x, wavelet = m, n.level = k,         shrink.fun = p, 
                                       thresh.fun = u, threshold = NULL, 
                                       thresh.scale = l, xform = "modwt", 
                                       noise.variance = -1, reflect = TRUE), 
       w$wavelet, w$nlevel, w$schrinkfun, w$threshfun, 
       w$threshscale, MoreArgs = list(x = xxi))
}

mapply3 <- function(i, w2, xx){
    xxi <- xx[[i]]
    w3  <- w2[[i]]
    z2  <- seq(1, length(xxi), 1)
    lapply(xxi, mapply2, w3)
}

This is called as follows result <- lapply(z, mapply3, w2, xx). For the purposes of checking that the code could even run I used the following form of xx (whether or not this is structurally similar to the full version I do not know).

xx  <- list(list(c(1,2,3,4,5,6,7,5,4,3,2,4,3,2,3,5,4,3,2,3,4,5,6,3,2,1,2,3,5,4,3,3),
             c(0,3,1,4,1,2,7,5,4,1,3,4,9,2,7,5,1,3,2,2,4,7,6,4,2,1,1,1,5,1,3,1)),
        list(c(0,3,1,4,1,2,7,5,4,1,3,4,9,2,7,5,1,3,2,2,4,7,6,4,2,1,1,1,5,1,3,1),
             c(1,2,3,4,5,6,7,5,4,3,2,4,3,2,3,5,4,3,2,3,4,5,6,3,2,1,2,3,5,4,3,3)))
于 2015-09-01T00:33:05.713 回答