R:在函数内部使用 dplyr。 eval(expr, envir, enclos) 中的异常:未知列
R: Using dplyr inside a function. exception in eval(expr, envir, enclos): unknown column
我根据@Jim M 的 在 R 中创建了一个函数。
当我 运行 函数时出现错误:错误:未知列 'rawdata'
当查看调试器时,我收到消息:Rcpp::exception in eval(expr, envir, enclos): unknown column 'rawdata'
然而,当我查看环境时 window 我可以看到我已传递给函数的 2 个变量,它们包含具有 7 个级别因子的信息原始数据和具有 28 个级别的 refdata
function (refdata, rawdata)
{
wordlist <- expand.grid(rawdata = rawdata, refdata = refdata, stringsAsFactors = FALSE)
wordlist %>% group_by(rawdata) %>% mutate(match_score = jarowinkler(rawdata, refdata)) %>%
summarise(match = match_score[which.max(match_score)], matched_to = ref[which.max(match_score)])
}
这是使用 NSE(非标准评估)的函数的问题。使用 NSE 的函数在交互式编程中非常有用,但在开发中会导致许多问题,即当您尝试在其他函数中使用这些函数时。由于不直接评估表达式,R 无法在它所查看的环境中找到对象。我建议您阅读 here,最好阅读范围问题章节以获取更多信息。
首先您需要知道所有标准 dplyr
函数都使用 NSE。让我们看一下您的问题的大致示例:
数据:
df <- data.frame(col1 = rep(c('a','b'), each=5), col2 = runif(10))
> df
col1 col2
1 a 0.03366446
2 a 0.46698763
3 a 0.34114682
4 a 0.92125387
5 a 0.94511394
6 b 0.67241460
7 b 0.38168131
8 b 0.91107090
9 b 0.15342089
10 b 0.60751868
让我们看看 NSE 如何解决我们的简单问题:
首先是简单的互动案例作品:
df %>% group_by(col1) %>% summarise(count = n())
Source: local data frame [2 x 2]
col1 count
1 a 5
2 b 5
让我们看看如果我把它放在一个函数中会发生什么:
lets_group <- function(column) {
df %>% group_by(column) %>% summarise(count = n())
}
>lets_group(col1)
Error: index out of bounds
与您的错误不同,但它是由 NSE 引起的。完全相同的代码行在函数外工作。
幸运的是,您的问题有一个解决方案,那就是标准评估。 Hadley 还制作了 dplyr
中使用标准评估的所有函数的版本。它们只是普通函数加上末尾的 _
下划线。
现在看看这将如何工作:
#notice the formula operator (~) at the function at summarise_
lets_group2 <- function(column) {
df %>% group_by_(column) %>% summarise_(count = ~n())
}
这会产生以下结果:
#also notice the quotes around col1
> lets_group2('col1')
Source: local data frame [2 x 2]
col1 count
1 a 5
2 b 5
我无法测试你的问题,但使用 SE 而不是 NSE 会给你想要的结果。有关详细信息,您还可以阅读 here
我根据@Jim M 的
当我 运行 函数时出现错误:错误:未知列 'rawdata' 当查看调试器时,我收到消息:Rcpp::exception in eval(expr, envir, enclos): unknown column 'rawdata'
然而,当我查看环境时 window 我可以看到我已传递给函数的 2 个变量,它们包含具有 7 个级别因子的信息原始数据和具有 28 个级别的 refdata
function (refdata, rawdata)
{
wordlist <- expand.grid(rawdata = rawdata, refdata = refdata, stringsAsFactors = FALSE)
wordlist %>% group_by(rawdata) %>% mutate(match_score = jarowinkler(rawdata, refdata)) %>%
summarise(match = match_score[which.max(match_score)], matched_to = ref[which.max(match_score)])
}
这是使用 NSE(非标准评估)的函数的问题。使用 NSE 的函数在交互式编程中非常有用,但在开发中会导致许多问题,即当您尝试在其他函数中使用这些函数时。由于不直接评估表达式,R 无法在它所查看的环境中找到对象。我建议您阅读 here,最好阅读范围问题章节以获取更多信息。
首先您需要知道所有标准 dplyr
函数都使用 NSE。让我们看一下您的问题的大致示例:
数据:
df <- data.frame(col1 = rep(c('a','b'), each=5), col2 = runif(10))
> df
col1 col2
1 a 0.03366446
2 a 0.46698763
3 a 0.34114682
4 a 0.92125387
5 a 0.94511394
6 b 0.67241460
7 b 0.38168131
8 b 0.91107090
9 b 0.15342089
10 b 0.60751868
让我们看看 NSE 如何解决我们的简单问题:
首先是简单的互动案例作品:
df %>% group_by(col1) %>% summarise(count = n())
Source: local data frame [2 x 2]
col1 count
1 a 5
2 b 5
让我们看看如果我把它放在一个函数中会发生什么:
lets_group <- function(column) {
df %>% group_by(column) %>% summarise(count = n())
}
>lets_group(col1)
Error: index out of bounds
与您的错误不同,但它是由 NSE 引起的。完全相同的代码行在函数外工作。
幸运的是,您的问题有一个解决方案,那就是标准评估。 Hadley 还制作了 dplyr
中使用标准评估的所有函数的版本。它们只是普通函数加上末尾的 _
下划线。
现在看看这将如何工作:
#notice the formula operator (~) at the function at summarise_
lets_group2 <- function(column) {
df %>% group_by_(column) %>% summarise_(count = ~n())
}
这会产生以下结果:
#also notice the quotes around col1
> lets_group2('col1')
Source: local data frame [2 x 2]
col1 count
1 a 5
2 b 5
我无法测试你的问题,但使用 SE 而不是 NSE 会给你想要的结果。有关详细信息,您还可以阅读 here