Dom*_*ski 6 r dplyr nse tidyverse mutate
在阅读并重新阅读了许多"使用dplyr编程"指南之后,我仍然无法找到解决我的特定情况的方法.
据我所知,使用group_by_,mutate_和tidyverse功能,例如"字符串型"版本向弃用的标题,这enquo是要走的路.
然而,我的情况有所不同,我正在努力寻找一种整洁的方式来解决它的整洁方式.
实际上,我的目标是在函数内创建和操作数据帧.基于其他人创建(变异)新变量,使用它们等.
但是,无论我怎么努力,我的代码都会出错或者在包检查时返回一些警告,例如no visible binding for global variable ....
这是一个可重复的例子:
这就是我想要做的事情:
df <- data.frame(X=c("A", "B", "C", "D", "E"),
Y=c(1, 2, 3, 1, 1))
new_df <- df %>%
group_by(Y) %>%
summarise(N=n()) %>%
mutate(Y=factor(Y, levels=1:5)) %>%
complete(Y, fill=list(N = 0)) %>%
arrange(Y) %>%
rename(newY=Y) %>%
mutate(Y=as.integer(newY))
Run Code Online (Sandbox Code Playgroud)
一些常见的dplyr操作预期结果应该是:
# A tibble: 5 x 3
newY N Y
<fctr> <dbl> <int>
1 1 3 1
2 2 1 2
3 3 1 3
4 4 0 4
5 5 0 5
Run Code Online (Sandbox Code Playgroud)
我希望这段代码能够在函数内部安静地工作.以下是我处理非NSE问题的最佳尝试:
myfunction <- function(){
df <- data.frame(X=c("A", "B", "C", "D", "E"),
Y=c(1, 2, 3, 1, 1))
new_df <- df %>%
group_by_("Y") %>%
summarise(!!"N":=n()) %>%
mutate(!!"Y":=factor(Y, levels=1:5)) %>%
complete_("Y", fill=list(N = 0)) %>%
arrange_("Y") %>%
rename(!!"newY":="Y") %>%
mutate(!!"Y":=as.integer(newY))
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,我仍然收到以下消息:
myfunction: no visible global function definition for ':='
myfunction: no visible binding for global variable 'Y'
myfunction: no visible binding for global variable 'newY'
Undefined global functions or variables:
:= Y n.Factors n_optimal newY
Run Code Online (Sandbox Code Playgroud)
有办法解决吗?非常感谢!
编辑:我正在使用R 3.4.1,dplyr_0.7.4,tidyr_0.7.2和tidyverse_1.1.1
感谢我设法解决的问题,这是工作解决方案:
myfunction <- function(){
df <- data.frame(X=c("A", "B", "C", "D", "E"),
Y=c(1, 2, 3, 1, 1))
new_df <- df %>%
group_by_("Y") %>%
summarise_("N"=~n()) %>%
mutate_("Y"= ~factor(Y, levels=1:5)) %>%
complete_("Y", fill=list(N = 0)) %>%
arrange_("Y") %>%
rename_("newY"=~Y) %>%
mutate_("Y"=~as.integer(newY))
}
Run Code Online (Sandbox Code Playgroud)
非常感谢 :)
答案不在“使用 dplyr 编程”指南中,因为您的问题更为普遍。尽管您的代码处理非标准评估,但您的案例不需要它。如果删除处理非标准评估的代码,您将减少需要修复的问题数量。
尽管如此,一些重要的问题仍然存在——命名空间的问题。每当您在自己的包的函数内使用来自其他包的函数时,您都会处理命名空间。命名空间不是一个简单的主题,但如果您正在编写包,那么学习一点就会有所收获。我建议您阅读:从 r-pkgs.had.co.nz/namespace.html 中,找到“导入”部分并阅读其简介以及副标题“R 函数”。这将帮助您理解我在下面发布的步骤、代码和注释。
请按照以下步骤解决您的问题:
- 将 dplyr、magrittr 和 tidyr 添加到描述中。
- 将函数称为PACKAGE::FUNCTION()。
- 删除所有!!,:=因为在这种情况下你不需要它们。
- 从magrittr导入和导出管道。
- 从 rlang 导入.data。
- 将全局变量传递给 utils::globalVariables()。
- 重建、重新加载、重新检查。
# I make your function shorter to focus on the important details.
myfunction <- function(){
df <- data.frame(
X = c("A", "B", "C", "D", "E"),
Y = c(1, 2, 3, 1, 1)
)
df %>%
dplyr::group_by(.data$Y) %>%
dplyr::summarise(N = n())
}
# Fix check() notes
#' @importFrom magrittr %>%
#' @export
magrittr::`%>%`
#' @importFrom rlang .data
NULL
utils::globalVariables(c(".data", "n"))
Run Code Online (Sandbox Code Playgroud)