【问题标题】:dplyr with string and NSE at same timedplyr 同时带有字符串和 NSE
【发布时间】:2017-04-29 21:41:02
【问题描述】:

我喜欢使用字符输入来创建 dplyr 函数,因此对即将推出的新 v0.6.0 感到非常高兴。

为了好玩和学习当前 dplyr 版本 0.5.0.9004,我尝试制作一个可以接受字符参数和表达式 (NSE) 的灵活函数。

我确实成功了,但这不能做得更优雅吗?!

d = data.frame(v1=1:2, v2=9:8)

fixquo <- function(x){
  # 'fixquo' expects a enquo-ed object, then sees if enquo-ing needs to be 'reversed'...
  if(!length(tryCatch({ls(get_env(x))}, error=function(e) "empty"))) 
    x = as.name(as.character(UQ(x))[2])
    x
 }

Dtest <- function(d, x="v1", res="z"){
  x <- enquo(x) %>% fixquo()
  d %>% mutate(!!res := UQ(x))
}
Dtest(d)
Dtest(d, "v1")
Dtest(d, v1)
Dtest(d, v2)

【问题讨论】:

  • 什么是enquo?是从包裹里拿出来的吗?
  • dplyr 包!来自 github 上 tidyverse/dplyr 的新开发者版本,将于 2017 年 5 月晚些时候上线。
  • 您能否显示预期的输出,因为某些调用正在获取我的字符串,即Dtest(d, "v1")# v1 v2 z 1 1 9 v1 2 2 8 v1

标签: r dplyr nse


【解决方案1】:

由于 OP 的函数在某些情况下将 character 字符串作为输出,因此尚不清楚预期的输出

Dtest(d, "v1")
#   v1 v2  z
#1  1  9 v1
#2  2  8 v1
#Warning message:
#In ls(get_env(x)) : ‘get_env(x)’ converted to character string

在这里,我们假设函数应该计算以获取列 'v1' 的值

DtestN <- function(dat, x, res = "z"){
          lst <- as.list(match.call())
          x <- if(is.character(lst$x)) {
                  rlang::parse_quosure(x, env = parent.frame())
                  } else enquo(x)
          res <- if(!is.character(lst$res)) quo_name(enquo(res)) else res
          dat %>%
             mutate(UQ(res) := UQ(x)) 


 }


DtestN(d, 'v1')
#  v1 v2 z
#1  1  9 1
#2  2  8 2

DtestN(d, v1)
#  v1 v2 z
#1  1  9 1
#2  2  8 2

DtestN(d, v1, z)
#  v1 v2 z
#1  1  9 1
#2  2  8 2

DtestN(d, 'v1', z)
#  v1 v2 z
#1  1  9 1
#2  2  8 2

更多案例

DtestN(d, v1, new)
#  v1 v2 new
#1  1  9   1
#2  2  8   2 
DtestN(d, v1, 'new')
#   v1 v2 new
#1  1  9   1
#2  2  8   2


DtestN(d, v2, 'new')
#  v1 v2 new
#1  1  9   9
#2  2  8   8

【讨论】:

  • 我忘了提到库 dplyr 和 rlang 都被加载并附加了 library(dplyr) 和 library(rlang)。我应该在 get_env() 和 UQ() 函数之前使用 rlang::。
  • @HansSchepers 好的,没问题。我只是用了rlang,因为我没有附上它
  • dplyr 显然使 rlang 被添加到加载的命名空间中,而不是 search() 列表中。对我来说奇怪的是,用户输入的 UQ() 可以在 mutate() 函数中使用,即使 rlang 不在搜索列表中。自己使用 UQ() (例如在定义像上面的 fixquo() 这样的函数时)在没有 rlang:: 的情况下是错误的!
  • @HansSchepers 我认为它仍在开发中。可能会在新版本之前修复
  • 同样令人惊讶的是,即使函数定义中没有默认值,DtestN(d) 也可以在没有指定参数 x 的情况下工作!?还有一个新的 enquo-ing 效果..! mutate() 不关心,将结果列 'z' 定义为 NULL,所以原来的 d 出来了。
猜你喜欢
  • 2018-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多