fil*_*fig 5 r tidyr tidyeval rlang
我正在一个长数据库(full_database)上运行一个函数,该数据库有两个主要组,我需要在每个组的多个子集上执行各种线性模型。
然后,我将 R^2、调整后的 R^2 和 p.value 提取到数据框中,其中每一行对应于一次比较。由于有 30 种不同的情况,我有另一个小标题,其中列出了函数参数所在的所有可能性( possibility )。
原始函数的脚本是:
database_correlation <- function(id, group) {
require(dplyr)
require(tidyr)
require(rlang)
id_name <- quo_name(id)
id_var <- enquo(id)
group_name <- quo_name(group)
group_var <- enquo(group)
corr_db <- full_database %>%
filter(numid==!!id_name) %>%
filter(major_group==!!group_name) %>%
droplevels()
correlation <- summary(lm(yvar~xvar, corr_db))
id.x <- as.character(!!id_var) #Gives out an error: "invalid argument type"
group.x <- as.character(!!group_var) #Gives out an error: "invalid argument type"
r_squared <- correlation$r.squared
r_squared_adj <- correlation$adj.r.squared
p_value <- correlation$coefficients[2,4]
data.frame(id.x, group.x, r_squared, r_squared_adj, p_value, stringsAsFactors=FALSE)
}
Run Code Online (Sandbox Code Playgroud)
然后我运行该函数:
correlation_all <- lapply(seq(nrow(possibilities)), function(index) {
current <- possibilities[index,]
with(current, database_correlation(id, database))
}) %>%
bind_rows()
Run Code Online (Sandbox Code Playgroud)
我已经评论了出现错误的部分(id.x 和 group.x 分配),并且我尝试了多种替代方案(我将使用 id.x 作为示例):
最后一个选项(粗体)即使没有取消引号也可以工作,如果我在过滤 full_database 时直接使用filter(numid==id_name)删除 bang bang (!!) ,情况也是如此,但我可以'不明白为什么。通过使用 TRUE 和 FALSE 进行测试,R 可能会将 bang bang 解释为双重否定,并且由于它需要布尔值,因此会抛出错误。
感谢您的帮助!
直接使用idand group- 我假设这些是传入的字符串,所以我认为不需要将 quosure 强制为字符串。此外, !!可以在支持整洁评估的函数内部使用。确定这一点的简单第一步是“该函数来自基本 R 包”。as.character()是,所以它不起作用。
如果您决定将 quosure 转换为字符串,则可以使用 将rlang::as_name()相应的符号作为字符串检索。这是推荐的方法。
通过使用 TRUE 和 FALSE 进行测试,R 可能会将 bang bang 解释为双重否定,并且由于它需要布尔值,因此会抛出错误。
你的假设是正确的。
最后一个选项(粗体)即使没有取消引号也可以工作,如果我在过滤 full_database 时使用 filter(numid==id_name) 删除 bang bang (!!) ,情况也是如此
整洁评估的核心是在正确的环境中评估符号,或者至少这是我的看法。这filter()是有效的,因为它查找符号id_name,在数据中(它查找的第一个位置)没有找到它,然后在封闭环境中查找,找到它,并评估该语句。
id_name想象一下,如果您有一个在数据中命名的列。您如何区分数据id_name和封闭环境中的数据。好吧,如果您想要数据的值,您可以使用.data$id_name(另一个 rlang 构造)。如果您想要数据之外的值,请使用!!。这告诉支持整洁评估的函数查看规则。quosure 标识了它是在哪个环境中定义的。然后它会在该环境中评估该符号,确保不会与数据中的名称发生冲突。