制定函数以向 mapply 函数提供变量

Formulating a function to supply variables to a mapply function

我有以下功能,将其放在第一个示例中时效果很好。但是,我希望有两个变量在 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 系列来执行此操作。结果应该与在单独的可变数据提要中两次应用正确的第一个示例相同,但连接为一个列表。

编辑

按照frank的回复。提出的一个问题是,如果 MoreArgs=list ( x = ( xx[[i]][[1]] )) 是 -- MoreArgs=list(x=(xx[[ i ] ][[ j ]]))),这意味着将在函数中引入一个新变量 - j - 根据将其添加到上面的解决方案中,该变量不包含在任何部分中。

不确定您要解决的问题我只能说下面代码的结果是 运行s 并且答案与您第一次获得的结果一致尝试。

我创建了一个名为 mapply2 的函数,如下所示。

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]])))
}

请注意,我通过与其余输入相同的变量对列表 xx 进行了索引,这纯粹是因为 w2 和 xx 是相同长度的列表。 (这可以接受吗?)

然后使用 lapply、

为每个 w2 和 xx 调用该函数
result <- lapply(z, mapply2)

另请注意,函数输入(或缺少输入)要求从包含 w2 和 xx 的相同环境调用 mapply2。

编辑: 在无法访问完整示例的情况下,我只能猜测如何修改我的答案。但我最好的猜测是

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)
}

这个叫法如下result <- lapply(z, mapply3, w2, xx)。为了检查代码甚至可以 运行 我使用了以下形式的 xx(我不知道这在结构上是否与完整版本相似)。

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