抱歉,标题很糟糕,但是很难解释。我要使用以下数据和函数来汇总数据:
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
:对于每个{{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
有什么想法吗?
答案 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
中进行编程的一般信息。
请让我知道该解决方案是否仍然存在问题/不够可靠。