【问题标题】:create a tibble where one column is a function创建一个小标题,其中一列是一个函数
【发布时间】:2018-06-28 12:31:35
【问题描述】:

假设我有一个看起来像这样的小标题:

library(tidyverse)
tib <- tibble (a = 1:3, b = 4:6, d = -1:1)

我想在这个 tibble 中添加一列,其中每个条目都是一个带有参数 a、b 和 d 的函数(如 f(x) = ax^2 + bx +d)。 这意味着(例如)在第一行中我想添加函数 f(x) = 1 x ^2 + 4 x -1,依此类推。

我尝试了以下方法:

tib2 <- tib %>%
   mutate(fun = list(function(x) {a*x^2+b*x+d}))

这不起作用,因为函数不知道 a、b 和 d 是什么。

我设法使用函数 mapply

构建了一个变通解决方案
lf <- mapply(function(a,b,d){return(function(x){a*x^2 + b*x + d})}, tib$a, tib$b, tib$d)
tib3 <- tib %>% 
  add_column(lf)

我想知道是否有人知道在 tidyverse 中执行此操作的更优雅的方式。感觉好像有一种方法可以使用 purrr 包中的 map 函数,但我没有设法让它工作。

谢谢

【问题讨论】:

  • 什么是x?在tib %&gt;% mutate(fun = list(function(x) {a*x^2+b*x+d})) 中,您将整个 tibble 作为参数传递,因此您希望 tibble$a 乘以 tibble-squared 等?
  • 所以我想要的是 fun 是一个包含函数的列。 x 只是这些函数的参数。因此,如果一切正常(在 tib3 中),那么 select(tib2, fun)[[1]][[1]](1) 应该返回 a*1^2+b*1+d,其中案例 a、b 和 d 是 1,4 和 -1。
  • 一般来说,你可以很容易地写出像fun &lt;- function(x, df=tib) with(df, a*x^2 + b*x + d)这样的函数......所以fun(1)会返回4 7 10等等。将这样的函数附加到tibble的想法是什么?这样每次都会计算结果,而不是将结果存储在静态列中?
  • 您可以将函数存储在数据框中(也许也可以存储在 tibble 中,我从来没有故意将 tibbles 用于任何严重的事情,所以我真的不知道)但是使这个有用可能会很棘手。
  • 感谢您的意见。我想将函数存储在 tibble 而不是它的输出中的原因是,我需要大量输入变量的输出,因此将它们全部存储似乎是不明智的。您的解决方案似乎也非常适合我的需求:)

标签: r list tidyverse purrr tibble


【解决方案1】:

当您在示例中使用mutate 时,您给它一个包含一个元素(函数)的列表。所以这个函数被回收用于所有其他行。此外,在函数的定义中,它不具有a、b 或d 的任何可见性。

您可以改用pmap,这样每一行都有自己的功能。

tib2 <- tib %>%
  mutate(
    fun = pmap(
      list(a, b, d),
      ~function(x) ..1 * x^2 + ..2 * x + ..3))

tib2
#> # A tibble: 3 x 4
#>       a     b     d    fun
#>   <int> <int> <int> <list>
#> 1     1     4    -1  <fun>
#> 2     2     5     0  <fun>
#> 3     3     6     1  <fun>

tib2$fun[[1]](1)
#> [1] 4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多