2015-08-31 2 views
1

У меня есть следующая функция, которая при размещении в первом примере отлично работает. Однако я хотел бы, чтобы две из переменных имели дополнительно два списка в функции mapply, чтобы предоставить два результата в любой форме. переменная w2 - это список с двумя компонентами, а xx - список с 2 векторами.Формулировка функции для передачи переменных функции mapply

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 или, возможно, я могу использовать другое семейство приложений для этого. Результат должен быть тем же самым, что и применение первого правильного примера дважды в отдельных передачах переменных данных, но в качестве списка.

EDIT

После réponse с откровенным. Вопрос о том, как бы вы переформулировали функцию ответа на выражение, если MoreArgs = list (x = (xx [[i]] [[1]])) был - MoreArgs = list (x = (xx [[i] ] [[j]]))), что означает, что в функцию-j была введена новая переменная, которая не включается ни в одну из частей, как добавление этого к вашему решению выше.

ответ

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

Обратите внимание, что я проиндексировал список хх той же переменной, как и остальные части ввода, только потому, что w2 и хх были списки одинаковой длины. (Это приемлемо?)

Функция затем вызывается для каждого w 2 и хх с помощью lapply,

result <- lapply(z, mapply2) 

отметить также, что функция входа (или отсутствие там) требует, чтобы mapply2 вызывается из той же среды, которая содержит w2 и xx.

Редактировать: Без доступа к полному примеру я могу только предположить, как изменить свой ответ. Но моя догадка, что что-то вдоль линий

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

Благодарим за ваш ответ. Ваша петля делает то, что я намеревался сделать. В принципе длина xx и w2 одинакова. По какой-то причине z не берется и выдает ошибку, поскольку она не распознает ее как числовой и векторный, а как [1] ​​«целое число» «числовой» «вектор» «data.frameRowLabels». Даже когда я изменил на numeric с помощью as.numeric, ошибка продолжается. Возможно, это связано с последним комментарием. Непонятно, что это означает тем же самым environement. – Barnaby

+0

Я рад, что цикл делает то, что вам нужно. Последний комментарий к средам был просто признанием ленивости, я не включил w2 в качестве вклада в mapply2. Если код запускается только как один скрипт, то, вероятно, это не имеет значения. Боюсь, я не могу полностью понять остальную часть вашего комментария, описываете ли вы ошибку, возникающую с mapply2 или с исходным кодом? – frank2165

+0

Моя ошибка w2 в реальной вещи нуждается в двух числах для индекса MoreArgs = list (x = (xx [[i]] [[1]]))) – Barnaby

Смежные вопросы