r - 数据框中的函数
问题描述
我想创建一个函数列表并将它们放在一个数据框中。它使我在余下的工作中更容易操作这些功能。我想在对字符/因子列进行分组时放置 ecdf 和分位数函数。
我做了这样的事情:
library(tidyverse)
quantilef = function(x) {
qf = function(p){
return(quantile(x, probs = p))
}
return(qf)
}
ecdfdf = iris %>%
group_by(Species) %>%
summarise(ecdf_ = list(ecdf(Sepal.Length)),
qf_ = list(quantilef(x = Sepal.Length)))
ecdf 按预期工作:
> ecdfdf %>% mutate(p = map_dbl(.x = ecdf_, .f = ~.x(5)))
# A tibble: 3 x 4
Species ecdf_ qf_ p
<fct> <list> <list> <dbl>
1 setosa <ecdf> <fn> 0.56
2 versicolor <ecdf> <fn> 0.06
3 virginica <ecdf> <fn> 0.02
但是分位数给出NA
:
> ecdfdf %>% mutate(q10 = map_dbl(.x = qf_, .f = ~.x(0.5)))
# A tibble: 3 x 4
Species ecdf_ qf_ q10
<fct> <list> <list> <dbl>
1 setosa <ecdf> <fn> NA
2 versicolor <ecdf> <fn> NA
3 virginica <ecdf> <fn> NA
我知道这是可行的quantilef
,因为它在数据框之外工作:
> qfsl = quantilef(x = iris$Sepal.Length)
> qfsl(0.5)
50%
5.8
到底是怎么回事?我该如何解决这个问题?
解决方案
我认为问题在于,当您为 创建函数列表时qf_
,您正在传递一个参数,x
该参数是延迟评估的。当你去调用函数时,x
调用环境中不再存在。
解决此问题的一种方法是包装x
在quosure
调用函数时对其进行评估的 a 。
这是一个代表:
library(tidyverse)
quantilef = function(x) {
y <- rlang::new_quosure(x)
qf <- function(p){
return(quantile(rlang::eval_tidy(y), probs = p))
}
return(qf)
}
ecdfdf = iris %>%
group_by(Species) %>%
summarise(ecdf_ = list(ecdf(Sepal.Length)),
qf_ = list(quantilef(x = Sepal.Length)))
ecdfdf %>% mutate(q10 = map_dbl(.x = qf_, .f = ~.x(0.5)))
#> # A tibble: 3 x 4
#> Species ecdf_ qf_ q10
#> <fct> <list> <list> <dbl>
#> 1 setosa <ecdf> <fn> 5
#> 2 versicolor <ecdf> <fn> 5.9
#> 3 virginica <ecdf> <fn> 6.5
由reprex 包(v0.3.0)于 2020-04-14 创建
推荐阅读
- html - 图片未加载到网页上
- javascript - 如何在节点列表上使用带有 for 循环的 match() 方法
- laravel - 如何修复“未捕获的 ReferenceError:Vue 未在 vuetemplatetest.2.html:19 中定义”
- reinforced-typings - 使用强化类型,你可以在 TsInterface 上默认设置属性吗?
- php - 批处理参数必须是 JSON 数组
- java - 我怎样才能让这个 if 语句正常工作?
- python - 上次刷新 Django/Celery 后 9 天为用户安排任务
- node.js - 无法从我的服务器获得响应。为什么?
- powerbi - 总计去年每天的销售额无法正常工作
- swift - 为返回做准备