r - R:`f(x) 中的错误:尝试使用函数列作为 tibble 中的参数时找不到函数“f”`
问题描述
我正在尝试在 R 中的数据帧(tidyverse tibbles)中使用函数,但遇到了一些困难。以下是我的问题的最小(琐碎)示例。
假设我有一个接受三个参数的函数:x
andy
是数字,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
应用于这三列的列。它应该27
和227
以前一样。但是当我尝试这个时,我得到一个错误:
> test_frame %>% mutate(result=func_then_add(.$arg_1, .$arg_2, .$func))
Error in f(x) : could not find function "f"
为什么会发生这种情况,以及如何正确获得我想要的?我承认我是“函数式编程”的新手,所以也许我只是在犯一个明显的语法错误......
解决方案
不是最优雅的,但我们可以做到:
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_dbl
which 返回与其对象相同的数据类型:
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
推荐阅读
- django - Django 表单数据未保存到数据库中
- checksum - 在控制单元消息中查找 CRC/校验和
- python - 检查我的程序的正确运行
- npm - package.json 指定库的版本
- java - 杰克逊中的多态反序列化为特定字段设置值 null
- c# - AspNetCoreModuleV2 问题 .NET Core 3.0
- java - 向多个收件人发送电子邮件时,Java Mail API 需要很长时间
- android - 如果我尝试在 android 8.1 下使用 GPU 委托会发生什么
- javascript - 根据选定的搜索条件和搜索关键字显示结果表
- android - 是否可以将原生库/移动 SDK 与 Flutter 集成?