Подтвердить что ты не робот

Использовать... для изменения вложенного списка в функциональном

В R я пытаюсь создать способ преобразования функциональных параметров, указанных в ..., в значения в предварительно определенном списке в функции закрытия.

Я хотел бы сделать что-то вроде этого:

function_generator <- function(args_list = list(a = "a", 
                                                b = "b", 
                                                c = list(d = "d", 
                                                         e = "e")){

    g <- function(...){
         ## ... will have same names as args list
         ## e.g. a = "changed_a", d = "changed_d"
         ## if absent, then args_list stays the same e.g. b="b", e="e"
         arguments <- list(...)
         modified_args_list <- amazing_function(arguments, args_list)
         return(modified_args_list)
         } 

    }

args_list будет отличаться каждый раз - его объект тела, который будет отправлен в запросе httr.

У меня есть функция, которая работает, если список не имеет вложенных списков:

substitute.list <- function(template, replace_me){

  template[names(replace_me)] <- 
    replace_me[intersect(names(template),names(replace_me))]

  return(template)

}

t <- list(a = "a", b="b", c="c")
s <- list(a = "changed_a", c = "changed_c")

substitute.list(t, s)
> $a
>[1] "changed_a"

>$b
>[1] "b"

>$c
>[1] "changed_c"

Но я не могу решить, как его изменить, чтобы он работал с вложенными списками:

## desired output
t <- list(a = "a", b = "b", c = list(d = "d", e = "e"))
s <- list(a = "changed_a", d = "changed_d")

str(t)
List of 3
 $ a: chr "a1"
 $ b: chr "b1"
 $ c:List of 2
  ..$ d: chr "d1"
  ..$ e: chr "e1"

amaze <- amazing_function(t, s)

str(amaze)
List of 3
 $ a: chr "changed_a"
 $ b: chr "b1"
 $ c:List of 2
  ..$ d: chr "changed_d"
  ..$ e: chr "e1"

Что может быть amazing_function? Я предполагаю, что какая-то рекурсия с использованием substitute.list могла бы работать, но не была в состоянии найти что-либо, поэтому я обращаюсь к вам, через Интернет, за помощью или ссылками, чтобы заставить его работать. Очень важно.

4b9b3361

Ответ 1

Последующая глубина первого посещения вложенного списка

postwalk<-function(x,f) {
  if(is.list(x)) f(lapply(x,postwalk,f))  else f(x)
}

Функция замены, которая возвращает измененный список, а не мутирует на месте

replace.kv<-function(x,m) {
   if(!is.list(x)) return(x)
   i<-match(names(x),names(m));
   w<-which(!is.na(i));
   replace(x,w,m[i[w]])
}

Пример

t<-list(a="a1", b="b1", c=list(d="d1", e="e1"))
s<-list(a="a2", d="d2")

str(postwalk(t,function(x) replace.kv(x,s)))
List of 3
 $ a: chr "a2"
 $ b: chr "b1"
 $ c:List of 2
  ..$ d: chr "d2"
  ..$ e: chr "e1"