如何使geom_function与两步函数配合使用?

huangapple go评论68阅读模式
英文:

How to get geom_function to work with a two-step function?

问题

我发现用言语很难解释我想做的事情,所以我只是将我的代码贴在下面。

fun <- function(a, x) {
  output <- a * dlnorm(a, 2.72 - x, 0.52)
  return(output)
}

fun2 <- function(x) {
  output2 <- integrate(fun, lower = 0, upper = 200, x = x)
  return(output2)
}

a <- seq(-5, 5, 0.1)

list <- list()

for (ai in 1:length(a)) {
  list[[ai]] <- fun2(a[[ai]])
}

list %>%
  map(pluck, "value") %>%
  unlist() %>%
  bind_cols(a) %>%
  ggplot(aes(x = `...2`, y = `...1`)) +
  geom_line()

所以我们首先有一个函数,它接受ax作为参数。然后我们创建另一个函数,它对x的值积分第一个函数,最后我们绘制对a的积分。

请注意,我通过使用for循环手动计算图表的曲线。我想避免使用for循环,而是直接通过geom_function来做到这一点。然而,我不知道如何处理这个问题。我已经尝试了以下方法:

ggplot() + 
  geom_function(fun = fun2) + 
  xlim(-5, 5)

但不幸的是,这不起作用。那么在代码中指定这个的正确方法是什么?

英文:

I find it really hard to explain what I am trying to do with words, so I am just going to post my code below.

fun &lt;- function(a, x) {
  output &lt;- a*dlnorm(a, 2.72 - x, 0.52)
  return(output)
}

fun2 &lt;- function(x) {
  output2 &lt;- integrate(fun, lower = 0, upper = 200, x = x)
  return(output2)
}

a &lt;- seq(-5, 5, .1)

list &lt;- list()

for(ai in 1:length(a)){
  list[[ai]] &lt;- fun2(a[[ai]])
}

list %&gt;% 
  map(pluck, &quot;value&quot;) %&gt;% 
  unlist() %&gt;% 
  bind_cols(a) %&gt;% 
  ggplot(aes(x = `...2`, y = `...1`)) + 
  geom_line()

So we first have one function which takes on arguments of a and x. Then we make another function that integrates the first one over the values of x and finally we plot the integral over the values of a.

Notice that I am computing the curve for the plot manually by using a for loop. I would like to avoid using the for loop and I would like to directly do this via geom_function. However, I don't know how to approach this. I've been trying this:

ggplot() + 
  geom_function(fun = fun2) + 
  xlim(-5, 5)

But unfortunately that doesn't work. So what is the proper way to specify this in the code?

答案1

得分: 1

integrate函数不会从您的向量输入返回一个向量。它只期望单一输入,并返回一个结构作为输出,例如:

> str(fun2(1))
List of 5
 $ value       : num 6.39
 $ abs.error   : num 9.92e-06
 $ subdivisions: int 6
 $ message     : chr "OK"
 $ call        : language integrate(f = fun, lower = 0, upper = 200, x = x)
 - attr(*, "class")= chr "integrate"

所以您需要做的是让fun2返回一个与x相同形状的值向量。这涉及使用循环,但您可以通过使用Vectorize函数来隐藏它。例如,

fun2 <- function(x) {
  # 此定义仅处理标量x
  integrate(fun, lower = 0, upper = 200, x = x)$value
}
# 通过循环处理向量x
fun2 <- Vectorize(fun2)

现在geom_function(fun = fun2)将可以正常工作。

英文:

The integrate function doesn't return a vector from your vector input. It expects just a single input, and returns a structure as output, e.g.

&gt; str(fun2(1))
List of 5
 $ value       : num 6.39
 $ abs.error   : num 9.92e-06
 $ subdivisions: int 6
 $ message     : chr &quot;OK&quot;
 $ call        : language integrate(f = fun, lower = 0, upper = 200, x = x)
 - attr(*, &quot;class&quot;)= chr &quot;integrate&quot;

So what you need to do is make fun2 return a vector of values of the same shape as x. That involves a loop, but you can hide that by using the Vectorize function. For example,

fun2 &lt;- function(x) {
  # This definition only handles a scalar x
  integrate(fun, lower = 0, upper = 200, x = x)$value
}
# This makes it handle a vector x by looping over the values
fun2 &lt;- Vectorize(fun2)

Now geom_function(fun = fun2) will be fine with it.

huangapple
  • 本文由 发表于 2023年6月19日 03:31:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76502234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定