标签: tidyeval

连接定语和字符串

我正在寻找一种方法来连接 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)

r dplyr tidyeval rlang

4
推荐指数
1
解决办法
928
查看次数

示例问题:使用dplyr编程

参考:http://dplyr.tidyverse.org/articles/programming.html

此代码工作正常:

df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = sample(5), 
  b = sample(5)
)


my_summarise <- function(df, group_by) {
  group_by <- enquo(group_by)
  print(group_by)

  df %>%
    group_by(!!group_by) %>%
    summarise(a = mean(a))
}

my_summarise(df, g1)
Run Code Online (Sandbox Code Playgroud)

但是,如果我们将此函数包装在另一个函数中并进行调用,则它将无效.是因为名称只传递了一个级别?

wrapped_my_Summarize <- function(wdf, w_group_by){
  my_summarise(wdf, w_group_by)
}

wrapped_my_Summarize(df, g1)
Run Code Online (Sandbox Code Playgroud)

总的来说,我觉得上面的例子是一个冒险的例子

r dplyr tidyeval quosure

4
推荐指数
1
解决办法
79
查看次数

使用 tidy 评估选择命名的 [list] 元素

我试图理解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)

r non-standard-evaluation tidyeval rlang

4
推荐指数
1
解决办法
1661
查看次数

使用 `dplyr::mutate()` 从向量中指定的名称创建几个新变量

我想在数据框中创建几个新的空变量,在其中指定向量中的变量名称。如果我只指定一个变量名,但会中断多个变量名,则此方法有效。我尝试了一些以前的解决方案,但在这种情况下它们似乎不起作用,例如:


library(dplyr)

add_columns <- function(df, columns){
    columns <- quo(columns)
    mutate(df, !!columns := NA_character_)
}

columns <- c("x", "y")
iris %>% 
    add_columns(columns)

 Error: The LHS of `:=` must be a string or a symbol
Run Code Online (Sandbox Code Playgroud)

所需的输出是:

# A tibble: 150 x 7
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species x     y    
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <chr> <chr>
 1         5.10        3.50         1.40       0.200 setosa  NA    NA   
 2         4.90        3.00         1.40       0.200 setosa  NA    NA   
 3         4.70        3.20         1.30 …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyverse tidyeval

4
推荐指数
1
解决办法
1084
查看次数

dplyr()中的非标准评估和准范式不符合(天真)预期的工作

我正在尝试搜索数据库,然后"derived_name"在下面的可重现示例中使用从原始搜索派生的名称标记输出.我正在使用dplyr管道%>%,我在准静态评估和/或非标准评估方面遇到了麻烦.具体而言,使用在最终函数中count_colname派生自的字符对象无法对数据帧进行子集化."derived_name"top_n()

search_name <- "derived_name"
set.seed(1)
letrs <- letters[rnorm(52, 13.5, 5)]
letrs_count.df <- letrs %>%
    table() %>%
    as.data.frame()
count_colname <- paste0(search_name, "_letr_count")
colnames(letrs_count.df) <- c("letr", count_colname)
letrs_top.df <- letrs_count.df %>%
    top_n(5, count_colname)
identical(letrs_top.df, letrs_count.df)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

根据这个讨论,我认为上面的代码可行.而这篇文章引起我去尝试top_n_(),这似乎不存在.

我正在学习vignette("programming")哪个有点过头了.这篇文章让我尝试了!! sym()语法,这有效,但我不明白为什么!帮助理解为什么下面的代码工作将非常感激.谢谢.

colnames(letrs_count.df) <- c("letr", count_colname)
letrs_top.df <- letrs_count.df %>%
    top_n(5, (!! sym(count_colname)))
letrs_top.df
#   letr derived_name_letr_count
# 1    l                       5 …
Run Code Online (Sandbox Code Playgroud)

r dplyr non-standard-evaluation tidyeval quasiquotes

4
推荐指数
1
解决办法
305
查看次数

使用带逗号的as.formula

我想从用户那里动态获取条件,所以我构建了一个闪亮的应用程序,可以从输入字段中获取它们。问题是as.formula不适用于带有逗号的字符向量(没有效果的话)。

码:

all_conditions = 
  "condition1 ~ 0,
   condition2 ~ 1,
   condition3 ~ 2"

 my_dataset %>% group_by(id) %>%
  summarise(FLAG = case_when(
      as.formula(all_conditions) )
   )
Run Code Online (Sandbox Code Playgroud)

我得到:

评估错误:: 2:100:意外的','

我尝试使用paste和转义逗号没有成功。

r dplyr tidyeval

4
推荐指数
1
解决办法
281
查看次数

如何计算R quosure中的变量数?

假设我有一个函数,它使用非标准评估(NSE)从该数据框中获取数据框和不同数量的变量.是否有更快/更直接的方法来计算提供的变量数量而不是select()这些变量并计算列数?

# Works but seems non-ideal
nvar <- function(df, vars) {
  vars_en <- rlang::enquo(vars)
  df_sub <- dplyr::select(df, !!vars_en)
  ncol(df_sub)
}
nvar(mtcars, mpg:hp)
#> 4
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyverse tidyeval rlang

4
推荐指数
1
解决办法
116
查看次数

在 group_by() %&gt;% mutate() 函数调用中使用带引号的变量

可重现的例子

cats <-
  data.frame(
    name = c(letters[1:10]),
    weight = c(rnorm(5, 10, 1), rnorm(5, 20, 3)),
    type = c(rep("not_fat", 5), rep("fat", 5))
  )

get_means <- function(df, metric, group) {
  df %>%
    group_by(.[[group]]) %>%
    mutate(mean_stat = mean(.[[metric]])) %>%
    pull(mean_stat) %>%
    unique()
}

get_means(cats, metric = "weight", group = "type")
Run Code Online (Sandbox Code Playgroud)

我试过的

我希望得到两个值,而不是我得到一个值。看来 groupby 失败了。

我尝试了所有方法,包括使用 quo()、eval() 和替换 ()、UQ()、!! 以及许多其他方法来尝试使 group_by() 中的内容起作用。

这看起来非常简单,但我无法弄清楚。

代码推理

将变量放在引号中的决定是因为我在 ggplot aes_string() 调用中使用它们。我在函数中排除了 ggplot 代码以简化代码,否则会很容易,因为我们可以使用标准评估。

r dplyr tidyeval

4
推荐指数
1
解决办法
1740
查看次数

R如何使用带有filter或filter_的curl curl?

我在评论者建议!! ensym的地方回答这个问题,我认为这可能是使用卷曲{{的好地方,但我无法使其正常工作(也许不适用?)。

在不使用filter_,eval / parse或quote-unquote的情况下,如何执行此过滤器操作?会帮助吗?

我的解决方案(1g)使用filter_和使用粘贴建立的条件。1a有效(但是可以使用{{}}吗?)

如果我们想按多个变量过滤该怎么办?这是您看到2g在下面工作的地方(而2a不再工作了)。

library(tidyverse)
set.seed(1234)
A <- matrix(rnorm(30),nrow = 10, ncol = 3) %>% as_tibble() %>% set_names(paste("var", seq(1:3), sep = ""))
varnames_1 <- c("var2")

(expected_result_1 <- filter(A, var2 > 0))
#> # A tibble: 3 x 3
#>     var1   var2   var3
#>    <dbl>  <dbl>  <dbl>
#> 1 -2.35  0.0645  0.460
#> 2  0.429 0.959  -0.694
#> 3 -0.890 2.42   -0.936

(answer_1a <- filter(A,!!ensym(varnames_1) > 0)) # works (thanks joran and aosmith)
#> # A …
Run Code Online (Sandbox Code Playgroud)

r filter dplyr tidyeval rlang

4
推荐指数
2
解决办法
165
查看次数

在 R 包中使用 tidy eval

我有一个stacked_plot()使用整洁评估来制作堆叠图的函数。我想将它包含在我的包中,并从该包中调用另一个函数来调用它。这是最小的例子:

stacked_plot <- function(data, what, by = NULL, date_col = date){

  by <- rlang::enquo(by)
  what <- rlang::ensym(what)
  date_col <- rlang::ensym(date_col)
  data <- data %>%
    dplyr::group_by(!!date_col, !!by) %>%
    dplyr::summarise(!!what := sum(!!what, na.rm = TRUE)) %>%
    dplyr::ungroup() %>%
    tidyr::complete(!!date_col, !!by, fill = rlang::list2(!!what := 0))

  p <- data %>%
    ggplot2::ggplot(ggplot2::aes(!!date_col, !!what, fill = !!by)) +
    ggplot2::geom_area(position = 'stack')
  print(p)
}

#' @importFrom rlang .data
call_plot <- function() {
  to_plot <- data.frame(date = rep(seq(lubridate::ymd('2020-01-01'),
                                       lubridate::ymd('2020-03-30'),
                                       by = '1 day'), each = …
Run Code Online (Sandbox Code Playgroud)

r dplyr r-package tidyeval rlang

4
推荐指数
1
解决办法
193
查看次数