【问题标题】:Formulating a function to supply variables to a mapply function制定函数以向 mapply 函数提供变量
【发布时间】:2015-08-31 20:10:34
【问题描述】:

我有以下功能,放在第一个示例中时可以正常工作。但是,我希望其中两个变量在 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 - 根据将其添加到上面的解决方案中,该变量不包含在任何部分中。

【问题讨论】:

    标签: r loops lapply sapply mapply


    【解决方案1】:

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

    我创建了一个名为 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 &lt;- 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)))
    

    【讨论】:

    • 感谢您的回答,您的循环完成了我的目标。原则上xx和w2的长度是一样的。由于某种原因,z 未被采用并产生错误,因为它不将其识别为数字和向量,而是将其识别为 [1]“整数”“数字”“向量”“data.frameRowLabels”。即使我通过 as.numeric 更改为数字,错误仍在继续。也许这与您最后的评论有关。不清楚同一个环境是什么意思
    • 我很高兴循环可以完成您需要的工作。关于环境的最后一条评论只是承认我很懒,我没有将 w2 作为 mapply2 的输入。如果代码只是作为单个脚本运行,那么它可能无关紧要。恐怕我不能完全理解您的其余评论,您是在描述 mapply2 或原始代码发生的错误吗?
    • 我的错w2在现实中需要两个数字来索引MoreArgs=list(x=(xx[[i]][[1]])))
    • 如果最后一个表达式 MoreArgs=list ( x = ( xx[[i]][[1]] )) 是 -- MoreArgs=list(x=(xx[[ i ]][[ j ]])))),这意味着将引入一个新变量 - j - 按照将其添加到上面的解决方案中。我编辑了问题,以便将其也包含在问题中。
    • @Barnaby 我已经更新了我的答案,我不能说我确定代码可以在完整版中运行而没有看到完整版。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2021-12-07
    • 2015-10-28
    相关资源
    最近更新 更多