Работает ли stat_function () в ggplot2 с аргументами, отличными от векторов? - PullRequest
0 голосов
/ 20 января 2019

Я пытаюсь напечатать некоторые значения (geom_point) и поверх этого нарисовать некоторую функцию (stat_function) с помощью ggplot2, однако я не могу отобразить функцию, потому что она имеет аргумент типа list.

Я хочу напечатать функцию create.new.func(x,W), которая получает два параметра (x, W), где x - это числовое значение, а W - список, содержащий две матрицы разных размеров. Я пытался использовать строку

stat_function(fun= create.new.func,aes(colour="sep1"),args = list(W=superW))

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

Computation failed in `stat_function()`: non-conformable arguments##

Конечно, create.new.func(x,W=superW) отлично работает для любого x. Весь фрагмент кода, который я видел до сих пор, кажется, использует только векторы для параметра args, поэтому мой вопрос.

Пример:

W <- list(matrix(c(1, -1, -1, 1), nrow = 2), matrix(c(1, 2)))

func <- function(x, W){
    sum(W[[2]] * (W[[1]] %*% c(1, x)))
}

ggplot() + 
    geom_point(aes(x = 0, y = 0)) + 
    theme_bw()+
    stat_function(fun = func, args = list(W), aes(colour = "black")) +
    scale_colour_manual("data", values = c("blue"))

1 Ответ

0 голосов
/ 20 января 2019

Per ?stat_function, fun должны быть векторизованы.stat_function создает вектор значений x длины n (по умолчанию 101) из диапазона значений x, передает его в функцию и отображает созданные значения x вместе с результирующими значениями y.Например,

library(ggplot2)

ggplot() + stat_function(aes(x = 0:1), fun = sqrt)

Обратите внимание, что x должен иметь диапазон;если x = 0, то результатом будет просто точка, даже если stat_function все равно создаст вектор значений x (которые все будут одинаковыми), то есть seq(0, 0, length.out = 101).

Быстрый способчтобы ваш код работал, нужно добавить полезный домен для x и перебрать x в func:

W <- list(matrix(c(1, -1, -1, 1), nrow = 2), matrix(c(1, 2)))

func <- function(x, W){
    sapply(x, function(x_i){
        sum(W[[2]] * (W[[1]] %*% c(1, x_i)))
    })
}

# it's vectorized now
func(1:10, W)
#> [1] 0 1 2 3 4 5 6 7 8 9

ggplot() + 
    geom_point(aes(x = 0, y = 0)) + 
    stat_function(aes(x = 0:1), fun = func, args = list(W = W))

В конечном итоге это не так отличный способ векторизации func, потому что он просто цикличен вместо написания лучшего кода / математики, поэтому он не очень эффективен.В этом случае 101 итерация простой функции все равно будет очень быстрой, поэтому не стоит затрачивать усилия на ее дальнейшую оптимизацию.Для более медленных и более сложных функций это может быть.

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