对不起,标题不好,但是很难解释。我要使用以下数据和函数来汇总数据:
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
进行分组,并按以下方式汇总V1
,V2
和V3
:对于这些变量的每个V
和n
中的每个值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))
有什么想法吗?
[我找到了一种方法,当将它作为附加参数写入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中进行编程的常规信息。
请让我知道此解决方案是否仍然存在问题/不够可靠。