【发布时间】:2020-01-23 22:27:15
【问题描述】:
我在使用 tidyr 包运行非标准评估 (nse) 表达式时遇到问题。
基本上,我想做的是扩展可能相同或不同的两列,以实现具有所有可能组合的数据框。问题是这将是一个函数,所以我不会提前知道列名。
这是一个最小的例子:
library(tidyr)
dummy <- data.frame(x = c("ex1", "ex2"), y = c('cat1', 'cat2')) # dataset
tidyr::expand(dummy, x, y) # using standard evaluation works
tidyr::expand_(dummy, c("x", "y")) # using the deprecated syntax works
# The following did not work:
tidyr::expand(dummy, one_of('x'), y) # using select syntax
tidyr::expand(dummy, vars('x', 'y')) # mutate_at style
tidyr::expand(dummy, .data[[cnae_agg]], .data[[cnae_agg]]) # mutate current style
tidyr::expand(dummy, sym('x'), sym('y')) # trying to convert to symbols
tidyr::expand(dummy, !!!enquos('x', 'y'))
tidyr::expand(dummy, !!('x'), y) # unquosure just one element
tidyr::expand(dummy, !!!c("x", "y")) # unquosure vector of strings
tidyr::expand(dummy, !!!c(quo("x"), quo("y"))) # unquosure vector that is being quosured before
所以,我有两个问题:
1) 使用 tidyr 扩展函数的正确语法是什么?
2) 我可能已经多次阅读Advanced R 关于准引用的章节,但我仍然不清楚为什么有几种不同的“风格”可以在 tidyverse 中使用nse,以及在哪里使用每个.
我基本上可以抛出几乎任何东西来选择/总结它会起作用,但是当使用 mutate 时,事情的反应会有所不同。
例如:
# mutate
mutate(dummy, new_var = .data[['x']]) # mutate basic style
mutate(dummy, new_var = !!'x') # this just attributes 'x' to all rows
# mutate at
mutate_at(dummy, .vars=vars('y'), list(~'a')) # this works
mutate_at(dummy, .vars=vars(!!'y'), list(~'a')) # this also works
mutate_at(dummy, .vars=vars('y'), list(~`<-`(.,!!'x'))) # if we try to use unquote to create an attribution it does not work
mutate_at(dummy, .vars=vars('y'), list(~`<-`(.,vars(!!'x')))) # even using vars, which works for variable selection, doesnt suffice
# select
select(dummy, x) # this works
select(dummy, 'x') # this works
select_at(dummy, vars(!!'x')) # this works
select_at(dummy, 'x') # this works
select_at(dummy, !!'x') # this doesnt work
这让我想到了我的 2) 问题。
是否有更新的指南,其中包含 tidyverse 样式的所有当前语法,重点关注每个“动词”的用法差异,例如在“变异”与“选择”中(即当一个工作而另一个工作时)没有)?
以及如何知道我是否必须在其他 tidyverse 包(例如 tidyr)中使用 mutate 或 nse 的 select 样式?
【问题讨论】:
-
不清楚
mutate_at(dummy, .vars=vars('y'), list(~(.,!!'x')))这里的逻辑。您正在选择“y”列,然后它是否分配给不同的列?在这种情况下,您可以在单独的步骤中使用rename或rename_at -
我同意这样做肯定会更好。我只是强调一些您可以使用通常的 mutate 进行的操作,但在使用 nse 和不同的风格时会变得非常混乱。例如,使用 mutate 进行归因很容易:mutate(dummy, x = y),但使用 mutate_at 和 nse 似乎很难。