首页 > 解决方案 > R:`f(x) 中的错误:尝试使用函数列作为 tibble 中的参数时找不到函数“f”`

问题描述

我正在尝试在 R 中的数据帧(tidyverse tibbles)中使用函数,但遇到了一些困难。以下是我的问题的最小(琐碎)示例。

假设我有一个接受三个参数的函数:xandy是数字,andf是函数。它执行f(x) + y并返回输出:

func_then_add = function(x, y, f) {
  result = f(x) + y
  return(result)
}

而且我有一些简单的功能可以用作f

squarer = function(x) {
  result = x^2
  return(result)
}

cuber = function(x) {
  result = x^3
  return(result)
}

自行完成,func_then_add如宣传的那样工作:

> func_then_add(5, 2, squarer)
[1] 27
> func_then_add(6, 11, cuber)
[1] 227

但是假设我有一个数据框(tidyverse tibble),其中两列用于数字参数,一列用于我想要的函数:

library(tidyverse)
library(magrittr)

test_frame = tribble(
  ~arg_1, ~arg_2, ~func,
  5, 2, squarer,
  6, 11, cuber
)

> test_frame
# A tibble: 2 x 3
  arg_1 arg_2 func  
  <dbl> <dbl> <list>
1     5     2 <fn>  
2     6    11 <fn>  

然后我想制作另一个result等于func_then_add应用于这三列的列。它应该27227以前一样。但是当我尝试这个时,我得到一个错误:

> test_frame %>% mutate(result=func_then_add(.$arg_1, .$arg_2, .$func))
Error in f(x) : could not find function "f"

为什么会发生这种情况,以及如何正确获得我想要的?我承认我是“函数式编程”的新手,所以也许我只是在犯一个明显的语法错误......

标签: rfunctional-programmingpurrrmagrittr

解决方案


不是最优雅的,但我们可以做到:

test_frame %>% 
  mutate(Res= map(seq_along(.$func), function(x)
        func_then_add(.$arg_1, .$arg_2, .$func[[x]]))) 

编辑:以上map都涵盖了整个数据,这并不是 OP 真正想要的。正如@January 所建议的,这可以更好地应用于:

Result <- test_frame %>% 
  mutate(Res= map(seq_along(.$func), function(x)
       func_then_add(.$arg_1[x], .$arg_2[x], .$func[[x]])))

Result$Res 

上面再次不是很有效,因为它返回一个列表。一个更好的选择(再次建议@January 是使用map_dblwhich 返回与其对象相同的数据类型:

test_frame %>% 
   mutate(Res= map_dbl(seq_along(.$func), function(x)
       func_then_add(.$arg_1[x], .$arg_2[x], .$func[[x]])))
# A tibble: 2 x 4
  arg_1 arg_2 func     Res
  <dbl> <dbl> <list> <dbl>
1     5     2 <fn>      27
2     6    11 <fn>     227

推荐阅读