我在使用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
这让我想到了我的第二个问题。
是否有一份更新的指南,列出了整个tidyverse风格的所有当前语法,重点关注每个“动词”使用上的差异,例如在'mutate'和'select'中(即一个何时起作用而另一个不起作用)?
如何知道我是否需要在其他tidyverse包(例如tidyr)中使用mutate或select样式的nse?
mutate_at(dummy, .vars=vars('y'), list(~
<-(.,!!'x')))
。您正在选择一个名为“y”的列,然后将其分配给另一列吗?如果是这种情况,您可以使用rename
或rename_at
在单独的步骤中完成。 - akrun