вложенный lapply для разрешения вызова функций с несколькими входами - PullRequest
1 голос
/ 02 октября 2019

РЕДАКТИРОВАТЬ: у меня есть несколько функций с несколькими аргументами, которые я хотел бы применить к списку списков. Одним из аргументов также является список списков. Обе функции имеют несколько параметров. два из которых я должен указать рекурсивно через списки списков. скажем, у меня есть два следующих списка списков:

mylist <- list(list(10,12,13,14,15), list(5,6,7,8,9))
m <- list(list(2,2,2,3,4), list(3,3,4,4,5))

и функции

func1 <- function(x, att1 = m, const = 10){
 e <- x^m + const
 return(e)
}

func2 <- function(x, att2 = m, const = 10){
 d <- sqrt(x)/m + const
 return(d)
}

Я не знаю, как обратиться к правильному аргументу, att1 или att2, когда я хочу вызвать каждую функцию. Я попробовал приведенную ниже функцию, используя eval(substitute(att1 = a))

nested_function <- function(df_list, FUN = func1, changing_param = a, ...){

 nested_output <- lapply(seq(df_list), function(i){
   lapply(seq(df_list[[i]]), function(j){
     FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]],...)
   })
 })

 return(nested_output)
}

result <- nested_function(df_list, FUN = func1, changing_param = 'att1 = a')

и получил следующую ошибку:

 Error in df[[i]] : object of type 'closure' is not subsettable 
6.
FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
...) 
5.
FUN(X[[i]], ...) 
4.
lapply(seq(df_list[[i]]), function(j) {
    FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
        ...)
}) 
3.
FUN(X[[i]], ...) 
2.
lapply(seq(df_list), function(i) {
    lapply(seq(df_list[[i]]), function(j) {
        FUN(df[[i]][[j]], eval(substitute(changing_param))[[i]][[j]], 
            ...) ... 
1.
nested_function(mylist, changing_param = m) 

Моя проблема заключается в том, как сделать так, чтобы вызов FUN() распознал a как att1 в func1 и att2 в func2, поскольку я должен назначить их для каждой функции (я не могу просто указать аргумент).

есть предложения?

1 Ответ

1 голос
/ 04 октября 2019

Если вам нужно динамически создавать имена параметров, вам часто приходится использовать do.call (по крайней мере, с базой R). Я уверен, что все ваши переменные должны были работать в вашем примере, так что вот адаптированная версия, которая запускается.

df_list   <- list(list(10,12,13,14,15), list(5,6,7,8,9))
param_list <- list(list(2,2,2,3,4), list(3,3,4,4,5))

func1 <- function(x, att1 = m, const = 10){
  e <- x^att1 + const
  return(e)
}

func2 <- function(x, att2 = m, const = 10){
  d <- sqrt(x)/att2 + const
  return(d)
}

nested_function <- function(df_list, param_list, FUN = func1, changing_param = "a", ...){
  nested_output <- lapply(seq(df_list), function(i){
    lapply(seq(df_list[[i]]), function(j){
      params <- list(df_list[[i]][[j]], param_list[[i]][[j]], ...)
      names(params)[2] <- changing_param
      do.call(FUN, params)
    })
  })

  return(nested_output)
}

nested_function(df_list, param_list, func1, changing_param = 'att1', const=1)
nested_function(df_list, param_list, func2, changing_param = 'att2', const=2)

Здесь мы передаем имя параметра, который мы хотим, в виде строки. Затем, когда мы создаем параметр, который мы собираемся передать функции, мы переименовываем параметр, который мы передаем, с указанным именем, а затем просто вызываем функцию.

...