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中。

这是一个reprex:

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

创建于 2020-04-14 由 reprex 软件包 (v0.3.0)

最新更新