使用「;获得;在dplyr中
其背景是,我有一些在一些地方使用plyr的遗留代码,直到几天前,plyr还没有更新以使其与R3.5兼容。我认为这是对plyr支持减少的一个信号,因此我正在考虑将plyr命令更改为dplyr。遗留代码中的ddply命令涉及一些“get”命令,用于引用名称包含在变量中的列。直接翻译将涉及以下类型的代码(一个人为的例子,但它说明了这一点)。它似乎可以工作,并使其与原始代码保持最接近,但这样做有什么陷阱吗?我得到的印象是,这不是制造商批准的使用dplyr编程的方式使用「;获得;在dplyr中,r,dplyr,plyr,R,Dplyr,Plyr,其背景是,我有一些在一些地方使用plyr的遗留代码,直到几天前,plyr还没有更新以使其与R3.5兼容。我认为这是对plyr支持减少的一个信号,因此我正在考虑将plyr命令更改为dplyr。遗留代码中的ddply命令涉及一些“get”命令,用于引用名称包含在变量中的列。直接翻译将涉及以下类型的代码(一个人为的例子,但它说明了这一点)。它似乎可以工作,并使其与原始代码保持最接近,但这样做有什么陷阱吗?我得到的印象是,这不是制造商批准的使用dplyr编程的方式 示例代码: library("dply
示例代码:
library("dplyr")
testFunction <- function(dataset, groupcol, varcol){
summaryTable <- dataset %>%
group_by(get(groupcol)) %>%
summarise(mean_var = mean(get(varcol)),
sd_var = sd(get(varcol)))
return(summaryTable)
}
testGroup <- "cyl"
testVar <- "mpg"
testFunction(mtcars, testGroup, testVar)
库(“dplyr”)
测试函数%
总结(平均值=平均值(获取(varcol)),
sd_var=sd(get(varcol)))
返回(汇总表)
}
testGroup我们可以使用sym
将其转换为符号
如果我们传递一个字符串变量,然后使用进行计算代码>
testFunction <- function(dataset, groupcol, varcol){
varcol <- rlang::sym(varcol)
dataset %>%
group_by(!! rlang::sym(groupcol)) %>%
summarise(mean_var = mean(!! varcol),
sd_var = sd(!! varcol))
}
testFunction(mtcars, testGroup, testVar)
# A tibble: 3 x 3
# cyl mean_var sd_var
# <dbl> <dbl> <dbl>
#1 4 26.7 4.51
#2 6 19.7 1.45
#3 8 15.1 2.56
最新版本的dplyr
允许使用bang-bang运算符(!!
)将变量插入函数调用中。应该避免使用get()
函数。您可以通过以下方式修复函数
testFunction <- function(dataset, groupcol, varcol){
groupcol <- as.name(groupcol)
varcol <- as.name(varcol)
summaryTable <- dataset %>%
group_by(!!groupcol) %>%
summarise(mean_var = mean(!!varcol),
sd_var = sd(!!varcol))
return(summaryTable)
}
testGroup <- "cyl"
testVar <- "mpg"
testFunction(mtcars, testGroup, testVar)
testFunction就我个人而言,我反对这里的一些正统说法,我只使用get
来处理以下一些情况:
testFunction <- function(dataset, groupcol, varcol){
dataset %>%
group_by(get(groupcol)) %>%
summarise(mean_var = mean(get(varcol)),
sd_var = sd(get(varcol)))
}
我发现get(x)
比更简单、更直观!!as.name(x)
或!!rlang::sym(x)
,考虑到过去几年中所有引用/取消引用实用程序的波动性,未来几年我可能会求助于基
命名空间中的内置函数。谢谢。出于兴趣,关于我最初的问题,为什么要避免使用get函数?只是教条,还是有功能上的原因?我想bang-bang比get短3个字符@Knackiedoo我想这可能更像是一个风格指南建议。要显示一个得到错误结果的示例并不容易,但是当使用get()
时,并不总是清楚要从何处提取特定变量。通常,当我在R代码中看到get()/assign()
时,是因为其他人从其他语言复制算法,而不是真正以“R方式”做事。使用符号和表达式(或表达式)或dplyr鼓励的quosures允许更灵活的代码,并且在使用比单个列名更复杂的表达式时表现更好。谢谢。MrFlick给出的答案与此类似,但在使用bang-bang之前没有转换成符号,而且它似乎可以工作。是否有特定的原因或情况需要首先转换为符号?按_at分组是一个很好的建议,但在所讨论的实际案例中,总结不会削减它,因为总结实际上比对所有变量应用单个函数复杂得多。@Knackiedooas.name
正在转换为symbolstr(as.name(testGroup))#symbol cyl
如果传递的参数是字符串,则它需要更改为symbol的条件。如果是不带引号的字符串,可以使用enquo
将其转换为quosure,然后执行代码>好的,我明白了。我非常确定as.name的理论编码问题不太可能是个问题,因此我将坚持使用基函数而不是sym。只是出于兴趣,我很好奇为什么“get”会遭到这样的反对。我刚才提到的sym help“与as.name()相反,它们事先将字符串转换为本机编码”。我相信你的话,get可能会出现环境/位置问题。只是想学习!
testFunction <- function(dataset, groupcol, varcol){
groupcol <- as.name(groupcol)
varcol <- as.name(varcol)
summaryTable <- dataset %>%
group_by(!!groupcol) %>%
summarise(mean_var = mean(!!varcol),
sd_var = sd(!!varcol))
return(summaryTable)
}
testGroup <- "cyl"
testVar <- "mpg"
testFunction(mtcars, testGroup, testVar)
testFunction <- function(dataset, groupcol, varcol){
dataset %>%
group_by(get(groupcol)) %>%
summarise(mean_var = mean(get(varcol)),
sd_var = sd(get(varcol)))
}
testFunction <- function(dataset, groupcol, varcol){
dataset %>%
group_by(.data[[groupcol]]) %>%
summarise(mean_var = mean(.data[[varcol]]),
sd_var = sd(.data[[varcol]]))
}