我正在寻找一种方法来连接 quosure 和一个结果是 quosure 的字符串。实际上,如果我使用paste0()and quo_name(),我就可以做到。但我想知道是否有更优雅的替代方案可以在我的包中编写函数。这是一个通用示例:
library(dplyr)
df <- data_frame(
z_1 = 1,
z_2 = 2,
y_1 = 10,
y_2 = 20
)
get_var <- function(.data, var) {
xx = enquo(var)
select(.data, paste0(quo_name(xx), "_1"), paste0(quo_name(xx), "_2"))
}
get_var(df, z)
# A tibble: 1 x 2
z_1 z_2
<dbl> <dbl>
1 1 2
Run Code Online (Sandbox Code Playgroud) 我试图理解rlang包中解释的非标准评估。考虑到这个目标,我的问题是:
如何编写
dplyr::select.list()符合整洁评估原则的函数?
这是我当前如何编写包装器的示例dplyr::select():
select_wrapper <- function(x, ...) {
vars <- rlang::quos(...)
dplyr::select(x, !!!vars)
}
Run Code Online (Sandbox Code Playgroud)
适用于数据框,例如,
> select_wrapper(mtcars, cyl, mpg)
> ## cyl mpg
> ## Mazda RX4 6 21.0
> ## Mazda RX4 Wag 6 21.0
> ## Datsun 710 4 22.8
> ## Hornet 4 Drive 6 21.4
> ## Hornet Sportabout 8 18.7
> ## Valiant 6 18.1
Run Code Online (Sandbox Code Playgroud)
但不在列表中:
attr(mtcars, "test") <- "asdf"
mtcars_list <- attributes(mtcars)
select_wrapper(mtcars_list, row.names, test)
> ## 1: …Run Code Online (Sandbox Code Playgroud) 我已将 curly-curly 与group_by和 一起使用,如rlang 公告summarise中所述。但是当我改变一个变量时我无法让它工作。目前使用 dplyr 执行此操作的最佳方法是什么?
假设我想提供一个不带引号的列名并对其进行变异,这是一个不起作用的玩具示例函数:
my_fun <- function(dat, var_name){
dat %>%
mutate({{var_name}} = 1)
}
my_fun(mtcars, cyl)
Run Code Online (Sandbox Code Playgroud)
该mutate行应该是什么才能将 mtcars 中的任何列更改为常量?
该.env代词用来指代对象的环境(而不是一个data.frame内)以及内业等dplyr动词,但返回一个错误slice_max。为什么?考虑以下函数:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(rlang)
f1 <- function(y) {
d <- tibble(x = runif(20))
d %>%
slice_max(order_by = .data$x, n = .env$y)
}
f2 <- function(y) {
d <- tibble(x = runif(20))
d %>%
filter(.data$x >= .env$y)
}
f3 <- function(y) {
d <- tibble(x = runif(20)) …Run Code Online (Sandbox Code Playgroud) 是否可以{{在 lm 公式中使用 rlang tidy 求值运算符?
我知道您可以使用双花括号来定义一个通用函数,如下所示:
my_scatter <- function(df, xvar, yvar) {
ggplot(df) +
geom_point(aes(x = {{xvar}}, y = {{yvar}}))
}
my_scatter(mpg, cty, hwy)
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有一种方法可以在公式中进行类似的调用,例如在 lm() 内部:
my_lm <- function(df, yvar, xvar) {
lm({{yvar}} ~ {{xvar}} , data = df)
}
my_lm(mpg, cty, hwy)
Run Code Online (Sandbox Code Playgroud) 我已经通读了《Programming with dplyr》并理解了这一点rename()并select()使用了整洁的选择。我试图将其与粘合语法结合起来,以使用新的双卷曲语法(rlang v0.4.0)创建自定义函数,但是我得到了额外的引号:
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
sel_var = "homeworld"
# Attempt at using (newer) double curly syntax:
starwars %>%
select("{{sel_var}}_old" := {{ sel_var }})
#> # A tibble: 87 x 1
#> `"homeworld"_old`
#> <chr>
#> 1 Tatooine
#> # ... with 77 more …Run Code Online (Sandbox Code Playgroud) 我正在努力理解如何使用{{ }}运算符在自定义函数中传递裸变量名称。当我将运算符与子句结合使用时,出现错误if。
该函数的工作原理:
f <- function(.data, .vars=NULL){
require(dplyr)
df = select(.data, {{ .vars }})
print(head(df))
}
f(iris, c(Species, Sepal.Length))
#> Loading required package: dplyr
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
#> Species Sepal.Length
#> 1 setosa 5.1
#> 2 setosa 4.9
#> 3 setosa 4.7
#> 4 setosa 4.6
#> 5 …Run Code Online (Sandbox Code Playgroud) 我想获取一个 tibble (或数据框),将其中一列转换为数字,仅选择同一列加上第三列,然后过滤掉 NA。
\n给出以下数据:
\nlibrary(tidyverse)\n\nset.seed(1) \n\nmytib <- tibble(a = as.character(c(1:5, NA)), \n b = as.character(c(6:8, NA, 9:10)), \n c = as.character(sample(x = c(0,1), size = 6, replace = TRUE)))\n\nvars <- c("a", "b")\nRun Code Online (Sandbox Code Playgroud)\n我创建了以下函数
\nconvert_tib <- function(var, tib){\n tib <- tib %>% \n mutate("{var}" = as.numeric({{ var }})) %>%\n dplyr::select({{ var }}, c) %>%\n filter(!is.na({{ var }}))\n return(tib)\n}\nRun Code Online (Sandbox Code Playgroud)\n并使用 purrr:map 运行它
\nmap(vars, ~ convert_tib(var = ., tib = mytib))\nRun Code Online (Sandbox Code Playgroud)\n遗憾的是,此代码的输出不会将向量转换为数字,也不会过滤掉 NA。我尝试了许多不同的策略,例如函数内部的ensym(var)and …
我正在尝试使用tidyeval进行编程。
我想编写一个函数为选定的结果变量运行逻辑回归模型:
library(tidyverse)
set.seed(1234)
df <- tibble(id = 1:1000,
group = sample(c("Group 1", "Group 2", "Group 3"), 1000, replace = TRUE),
died = sample(c(0,1), 1000, replace = TRUE))
myfunc <- function(data, outcome){
enquo_var <- enquo(outcome)
fit <- tidy(glm(!!enquo_var ~ group, data=data,
family = binomial(link = "logit")),
exponentiate = TRUE, conf.int=TRUE)
fit
}
myfunc(df, died)
Run Code Online (Sandbox Code Playgroud)
但是得到:
!enquo_outcome错误:参数类型无效
(请注意,实际情况涉及更复杂的功能)。
这可能吗?
我已经阅读了几个关于dplyr编程的指南,我仍然对如何解决使用非标准评估(NSE)评估构造/连接字符串的问题感到困惑.我意识到有更好的方法来解决这个例子,而不是使用NSE,但想要学习如何.
t <- tibble( x_01 = c(1, 2, 3), x_02 = c(4, 5, 6))
i <- 1
Run Code Online (Sandbox Code Playgroud)
这是我想要的结果,但是想要mutate()构造变量:
t %>% mutate(d_01 = x_01 * 2)
#> A tibble: 3 x 3
#> x_01 x_02 d_01
#> <dbl> <dbl> <dbl>
#> 1 1.00 4.00 2.00
#> 2 2.00 5.00 4.00
#> 3 3.00 6.00 6.00
Run Code Online (Sandbox Code Playgroud)
这是我第一次尝试使用字符串:
new <- sprintf("d_%02d", i)
var <- sprintf("x_%02d", i)
t %>% mutate(new = var * 2)
#> Error in mutate_impl(.data, dots) : …Run Code Online (Sandbox Code Playgroud)