ggplot2中的stat_function()是否可用于除矢量以外的args?

时间:2019-01-20 16:50:33

标签: r ggplot2 plot

我试图打印一些值(geom_point),并在上面用ggplot2绘制一些函数(stat_function),但是我无法绘制该函数,因为它具有类型为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 :(得分:0)

?stat_functionfun必须向量化。 stat_function在x值范围之间生成一个长度为n(默认为101)的x值的向量,并将其传递到函数中,并用生成的y值绘制创建的x值。例如,

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个迭代仍将非常快,因此不一定值得进一步优化它。对于较慢,更复杂的功能,可能是这样。