0

简短的摘要

dplyr 取消引用作为函数的参数失败,summarise其中引用的对象是使用的函数的参数summarise,并且该参数在 for 循环中分配。

循环

for(j in 1:1){
  sumvar  <- paste0("randnum",j)
  chkfunc(sumvar)
}

功能(此处略,下图)

chkfunc <- function(sumvar) {
sumvar <- enquo(sumvar)
[...]
    summarise(mn = mean(!!sumvar))

在此处输入图像描述

长总结

我有两列有时包含 NA,我想使用dplyr 非标准评估及其著名的取消引用(AKA bang bang !!)在一个 for 循环中总结每一列。

library(dplyr)
set.seed(3)
randnum1 <- rnorm(10)
randnum1[randnum1<0] <- NA
randnum2 <- rnorm(10)
randnum2[randnum2<0] <- NA
randfrm <- data.frame(cbind(randnum1, randnum2))
print(randfrm)

在此处输入图像描述

我们在下面看到 filter 函数可以很好地处理取消引用 (!!) 但 summarise 函数失败,返回“argument is not numeric or logical”错误。当我:=在“使用 dplyr 编程”小插图中使用 summarise 函数调用(此处未显示)时,也会发生同样的情况。最后,我确认了函数中的数字的。!!sumvarchkfunc

chkfunc <- function(sumvar) {
  sumvar <- enquo(sumvar)

  message("filter function worked with !!sumvar")
  outfrm <- randfrm %>%
    filter(!is.na(!!sumvar))
  print(outfrm)
  message("summarise function failed with !!sumvar")
  outfrm <- randfrm %>%
             filter(!is.na(!!sumvar)) %>%
             summarise(mn = mean(!!sumvar))
}
# Just one iteration to avoid confusion
for(j in 1:1){
  sumvar  <- paste0("randnum",j)
  chkfunc(sumvar)
}

在此处输入图像描述

4

1 回答 1

0

虽然我想要使用dplyr的答案,但以下内容适用于substituteeval不是使用dplyr函数(答案改编自Akrun 对 StackOverflow 问题“Unquote string in R's substitution command”的回答):

chkfunc <- function(sumvar) {
  outfrm <- eval(substitute(randfrm %>%
                            filter(!is.na(y)) %>%
                            summarise(mn = mean(y)),
                            list(y=as.name(sumvar))))
  print(outfrm)
} 

for(j in 1:2){
  sumvar  <- paste0("randnum",j)
  chkfunc(sumvar)
}

print(outfrm)

在此处输入图像描述

最后,我会注意到,虽然pullon 函数!!sumvar显示生成的类是数字的(即,相同的类和 的值randfrm$randnum1),但我发现在我使用and时,它!!sumvar都被视为字符串(即, ) ,因此警告。"randnum1filtersummariseargument is not numeric

于 2017-11-22T18:00:12.117 回答