Назначить один выход для функции с несколькими выходами новой функции - PullRequest
1 голос
/ 11 февраля 2020

У меня есть функция, которая дает мне один выход, который, однако, состоит из двух элементов. Примером этого может быть:

example <- function(x){
  sin <- sin(x)
  cos <- cos(x)
  output <- cbind(sin, cos)
  return(output)
}

Теперь моя идея состоит в том, чтобы построить отдельно sin и cos, каждый как функции от x. Я хотел бы избежать написания отдельной функции в этом контексте, так как два объекта лучше рассчитать все сразу. Если я пытаюсь:

x_grid = seq(0,1,0,0.05)
plot(x_grid, sapply(x_grid, FUN = example[1]))

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

Ошибка в примере [1]: объект типа 'замыкание' не может быть поднабором

Как действовать тогда? (обратите внимание, что я использую sapply, потому что мне нужно, чтобы моя функция имела дело с более чем одним значением x в моем реальном случае).

Ответы [ 3 ]

2 голосов
/ 11 февраля 2020

Если вы ищете неосновное графическое решение:

library(ggplot2)
example3 <- function(x){
  data.frame(
    x = x,
    sin = sin(x),
    cos = cos(x)
  )
}

x_grid=seq(0,1,0.05)
ggplot(data = example3(x_grid),
       aes(x=x)) +
  geom_line(aes(y = sin), color = "blue") +
  geom_line(aes(y = cos), color = "red")

С выводом: enter image description here

2 голосов
/ 11 февраля 2020

Ваша функция векторизована, поэтому вы можете ввести вектор и извлечь каждый столбец с помощью example(x_grid)[, "sin"] или example(x_grid)[, "cos"].

example(x_grid)
#                 sin          cos
#   [1,]  0.000000000  1.000000000
#   [2,]  0.049979169  0.998750260
#   [3,]  0.099833417  0.995004165
example(x_grid)[, "sin"]

# [1]  0.000000000  0.049979169  0.099833417  0.149438132  0.198669331
# [6]  0.247403959  0.295520207  0.342897807  0.389418342  0.434965534

Примечание: В этом случае sapply не рекомендуется, потому что сама функция была векторизована. sapply сделает его неэффективным. Вот иллюстрация к тесту:

library(microbenchmark)
bm <- microbenchmark(
  basic = example(x_grid)[, 1],
  sapply = sapply(x_grid, function(x) example(x)[1]),
  times = 1000L
)
ggplot2::autoplot(bm)


Если вы хотите построить обе функции, matplot() может построить каждый столбец одной матрицы.

x_grid <- seq(0, 10, 0.05)
matplot(x_grid, example(x_grid), type = "l")

1 голос
/ 11 февраля 2020

Появляется дополнительным параметром для seq

x_grid <- seq(0, 1, 0.05)

Небольшая модификация для передачи переменной в функцию и затем подмножество

plot(x_grid, sapply(x_grid, function(x) example(x)[1]))

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

example2 <- function(x) {
  within(list(), {
    sin <- sin(x)
    cos <- cos(x)
  })
}

plot(x_grid, sapply(x_grid, function(x) example2(x)$sin))

Если пример не упрощен, следующие работы без sapply

plot(x_grid, example2(x_grid)$sin)

Отображение обоих результатов

lapply(example2(x_grid), plot, x_grid)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...