Dplyr总结功能列表以及对其他数据列的依赖

时间:2019-12-04 22:54:23

标签: group-by dplyr summarize

抱歉,标题很糟糕,但是很难解释。我要使用以下数据和函数来汇总数据:

library(tidyverse)

# generate data
df <- map(1:4, ~ runif(100)) %>% 
  set_names(c(paste0('V', 1:3), 'threshold')) %>% 
  as_tibble() %>% 
  mutate(group = sample(c('a', 'b'), 100, replace = T))

# generate function list
fun_factory_params <- 1:10
fun_factory <- function(param){
  function(v, threshold){
    sum((v * (threshold >= 1/2))^param)
  }
}
fun_list <- map(fun_factory_params, fun_factory)

df %>% head(n = 5)
      V1     V2     V3 threshold group
   <dbl>  <dbl>  <dbl>     <dbl> <chr>
1 0.631  0.0209 0.0360     0.713 b    
2 0.629  0.674  0.174      0.693 b    
3 0.144  0.358  0.439      0.395 a    
4 0.0695 0.760  0.657      0.810 a    
5 0.545  0.770  0.719      0.388 b    

我想按df变量对group进行分组,并按以下方式汇总V1V2V3:对于每个{{1}这些变量的}和V(1到10)中的每个值n,我想计算fun_factory_params。为了以一种优雅的方式为每个sum((V * (threshold >= 1/2))^n)计算结果,我通过一个函数工厂创建了一个函数列表n

我尝试了以下操作并收到错误消息:

fun_list

我的问题来自df %>% group_by(group) %>% summarise_at(vars(V1,V2,V3), fun_list, threshold = threshold) Error in list2(...) : object 'threshold' not found 变量。我找不到使用我构建的函数列表并告诉R必须从每个数据组获取threshold参数的方法。我尝试将阈值变量移动到函数工厂的参数,并通过threshold调用在summarise_at内构建函数列表,但是遇到了同样的问题。本质上,我总是以某种方式使R离开正确的环境以按组评估阈值。使用purrr::map返回整个数据的阈值变量,因此不起作用。

但是,以下代码有效(但一次仅适用于给定的n值)这一事实使我认为有一种可以正确评估阈值的方法。

.$threshold

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

当我将threshold作为summarise_at函数的附加参数编写时,我找到了一种在正确的环境(分组数据)中对threshold进行评估的方法:您需要用{{ 1}}。

quo

我不是100%的理解。我认为通过引用可以确保阈值将使用在调用df %>% group_by(group) %>% summarise_at(vars(V1,V2,V3), fun_list, threshold = quo(threshold)) 时所发现的环境(即分组数据(我们想要的))进行评估。从本质上讲,引用变量不仅使其带有名称,而且还设置了对我们希望该变量进行评估的环境的引用。不引用,quo的求值是在不存在变量的不同环境(不确定哪个...)中进行的。可以在here中找到有关在threshold中进行编程的一般信息。

请让我知道该解决方案是否仍然存在问题/不够可靠。