Dplyr汇总功能列表,并依赖于其他数据列

问题描述 投票:1回答:1

对不起,标题不好,但是很难解释。我要使用以下数据和函数来汇总数据:

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:对于这些变量的每个Vn中的每个值fun_factory_params ](1到10),我想计算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

我的问题来自threshold变量。我找不到使用我构建的函数列表并告诉R必须从每个数据组获取threshold参数的方法。我尝试将阈值变量移动到函数工厂的参数,并通过summarise_at调用在purrr::map中构建函数列表,但是遇到了同样的问题。本质上,我总是以某种方式使R离开正确的环境以按组评估阈值。使用.$threshold返回entire数据的阈值变量,因此不起作用。

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

n <- 1
df %>% 
  group_by(group) %>% 
  summarise_at(vars(V1,V2,V3), ~ sum((. * (threshold >= 1/2))^n))

有什么想法吗?

group-by dplyr summarize
1个回答
0
投票

[我找到了一种方法,当将它作为附加参数写入threshold函数时,可以在正确的环境(分组数据)中对summarise_at进行评估:您需要用threshold引用quo

df %>% 
  group_by(group) %>% 
  summarise_at(vars(V1,V2,V3), fun_list, threshold = quo(threshold))

我不是我的理解的100%。我认为通过引用可以确保使用在调用quo时发现的环境评估阈值,该环境是分组数据(我们想要的)。从本质上讲,引用变量不仅使其带有名称,而且还设置了对我们希望该变量进行评估的环境的引用。不加引号,threshold的求值是在不存在变量的其他环境(不确定哪个...)中进行的。可以在dplyr中找到有关在here中进行编程的常规信息。

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

© www.soinside.com 2019 - 2024. All rights reserved.