标签: tidyeval

使用tidyeval为“ lm”编程功能

我正在尝试使用tidyeval(非标准评估)围绕“ lm”编写一个函数。使用基本R NSE,它的工作原理是:

lm_poly_raw <- function(df, y, x, degree = 1, ...){
  lm_formula <-
    substitute(expr = y ~ poly(x, degree, raw = TRUE),
               env = list(y = substitute(y),
                          x = substitute(x),
                          degree = degree))
  eval(lm(lm_formula, data = df, ...))
}

lm_poly_raw(mtcars, hp, mpg, degree = 2)
Run Code Online (Sandbox Code Playgroud)

但是,我还没有弄清楚如何使用tidyeval和编写此函数rlang。我认为substitute应该用代替enquo,并用代替!!。哈德利的Adv-R有一些提示,但我不知道。

r lm tidyeval

5
推荐指数
1
解决办法
353
查看次数

对多个dplyr过滤条件使用整齐的eval

我是整理eval并尝试编写泛型函数的新手 - 我现在正在努力的一件事就是为分类变量编写多个过滤条件.这就是我现在正在使用的 -

create_expr <- function(name, val){
   if(!is.null(val))
     val <- paste0("c('", paste0(val, collapse = "','"), "')")
   paste(name, "%in%", val)
}

my_filter <- function(df, cols, conds){
#   Args: 
#     df: dataframe which is to be filtered
#     cols: list of column names which are to be filtered
#     conds: corresponding values for each column which need to be filtered

cols <- as.list(cols)
conds <- as.list(conds)

args <- mapply(create_expr, cols, conds, SIMPLIFY = F)

if(!length(args))
  stop(cat("No filters provided"))

df <- df …
Run Code Online (Sandbox Code Playgroud)

r tidyverse tidyeval

5
推荐指数
1
解决办法
934
查看次数

dplyr .data 代词与“quosure”方法

dplyr v0.7.0中,.data引入了代词,允许我们用字符串引用变量。我只是好奇这种方法是否比“quosure”方法更受欢迎。例如,这是一种使用.data代词的方法:

varname <- "gear"
data_pronoun_method_df <- dplyr::mutate(mtcars, new_col = .data[[varname]] + 2)
Run Code Online (Sandbox Code Playgroud)

这与使用该quosure方法的示例进行了比较:

quo_varname <- rlang::quo(gear)
quo_method_df <- dplyr::mutate(mtcars, new_col = !! quo_varname + 2)
Run Code Online (Sandbox Code Playgroud)

两种方法产生相同的输出:

data_pronoun_method_df

# mpg cyl  disp  hp drat    wt  qsec vs am gear carb new_col
# 1  21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4       6
# 2  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4       6
# 3  22.8 …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyeval quosure

5
推荐指数
1
解决办法
865
查看次数

如何在lapply期间将ggplot x-label设置为等于变量名称?

我正在绘制一个 y 变量与多个 x 变量的关系图。我有一个使用 lapply 的工作解决方案。但是,我无法将 x 变量的名称写为每个图的 x 标签。这是我所拥有的一个简化示例:

目标是针对每个 x 变量绘制 y 变量,从而生成三个图,并将每个 x 变量的名称添加为 x 轴标签。

生成一个包含 1 个 y 变量和 3 个 x 变量的数据框:

df <- data.frame(y.variable=c(11:20), x1=c(21:30),x2=c(1:10),x3=c(31:40))
Run Code Online (Sandbox Code Playgroud)

一个应该以字符串形式检索变量名称的函数:

get_name <- function(v1) {deparse(substitute(v1))}
Run Code Online (Sandbox Code Playgroud)

生成 y 相对于 x 变量的图的函数:

generate_plot <- function(x.variable) {ggplot(data = df, aes(x.variable, y.variable )) +geom_point()  + xlab(get_name(variable.name))}
Run Code Online (Sandbox Code Playgroud)

调用 lapply 对 df 的每一列执行generate_plot:

lapply(df, generate_plot)
Run Code Online (Sandbox Code Playgroud)

这会产生三个图,每个图都将“variable.x”作为其 x 标签,而不是所需的变量名称 x1、x2 和 x3。

r ggplot2 lapply nse tidyeval

5
推荐指数
1
解决办法
2283
查看次数

将多组变量提供给正文中dplyr参数的函数

这是数据:

library(tidyverse)

data <- tibble::tribble(
  ~var1, ~var2, ~var3,  ~var4,    ~var5,
    "a",   "d",   "g",  "hello",    1L,
    "a",   "d",   "h",  "hello",    2L,
    "b",   "e",   "h",  "k",        4L,
    "b",   "e",   "h",  "k",        7L,
    "c",   "f",   "i",  "hello",    3L,
    "c",   "f",   "i",  "hello",    4L
  )
Run Code Online (Sandbox Code Playgroud)

和矢量,我想用:

filter_var <- c("hello")
groupby_vars1 <- c("var1", "var2", "var3")
groupby_vars2 <- c("var1", "var2")
joinby_vars1 <- c("var1", "var2")
joinby_vars2 <- c("var1", "var2", "var3")
Run Code Online (Sandbox Code Playgroud)

第2和第5,第3和第4个向量相同,但请假设它们不同并将它们保留为不同的向量.

现在我想创建一个通用函数,我可以在其中获取数据和这些向量来获得结果.

my_fun <- function(data, filter_var, groupby_vars1,groupby_vars2, joinby_vars1, joinby_vars2) {

  data2 <- data %>% filter(var4 == filter_var) …
Run Code Online (Sandbox Code Playgroud)

r dplyr purrr tidyeval rlang

5
推荐指数
1
解决办法
347
查看次数

使用dplyr/ggplot函数在for循环中调用许多变量

有时,在进行探索性分析或生成报告时,我们希望绘制许多变量的单变量分布.我可以在经过一些整洁的伎俩之后面对这个情节,但是有序因素,我想继续按照情节订购.

因此,为了更有效地完成它,我构建了一个简单dplyr/ ggplot基于函数.我使用vcd包的关节炎数据集在下面做了这个例子.

library(dplyr)
library(ggplot2)

data(Arthritis, package = "vcd")

head(Arthritis)

plotUniCat <- function(df, x) {
  x <- enquo(x)
  df %>%
    filter(!is.na(!!x)) %>%
    count(!!x) %>%
    mutate(prop = prop.table(n)) %>%
    ggplot(aes(y=prop, x=!!x)) +
    geom_bar(stat = "identity")
}

plotUniCat(Arthritis, Improved)
Run Code Online (Sandbox Code Playgroud)

我可以用很短的方式绘制格式化的图形,这很酷,但只有一个变量.

我尝试使用for循环调用多个变量,但它不起作用.代码运行,但没有任何反应.

variables <- c("Improved", "Sex", "Treatment")

for (i in variables) {
  plotUniCat(Arthritis, noquote(i))
}
Run Code Online (Sandbox Code Playgroud)

我搜索了这个,但对我来说仍然不清楚.有人知道我做错了什么或如何使它有效?

提前致谢.

r ggplot2 dplyr tidyeval

5
推荐指数
2
解决办法
484
查看次数

同时使用data.table和tidy eval:为什么group by不能按预期工作,为什么要插入?

我没有一个紧迫的用例,但想了解整齐的eval和data.table如何协同工作.

我有替代解决方案,所以我最感兴趣的是为什么,因为我希望能够更好地理解整齐的eval,这将有助于我在各种各样的用例中使用.

如何使用group by进行data.table +整理eval工作?

在以下示例中,我使用了rlang的开发版本.

更新

我根据Stefan F的答案和我的进一步探索更新了我的原始问题:我不再认为插入的〜是问题的重要部分,因为它也存在于dplyr代码中,但我有一个特定的代码:data.table + group by + quo我不明白为什么不起作用.

# setup ------------------------------------

suppressPackageStartupMessages(library("data.table"))
suppressPackageStartupMessages(library("rlang"))
suppressPackageStartupMessages(library("dplyr"))
#> Warning: package 'dplyr' was built under R version 3.5.1

dt <- data.table(
    num_campaign = 1:5,
    id = c(1, 1, 2, 2, 2)
)
df <- as.data.frame(dt)

# original question ------------------------

aggr_expr <- quo(sum(num_campaign))

q <- quo(dt[, aggr := !!aggr_expr][])

e <- quo_get_expr(q)
e
#> dt[, `:=`(aggr, ~sum(num_campaign))][]
dt[, `:=`(aggr, ~sum(num_campaign))][]
#> Error in `[.data.table`(dt, , `:=`(aggr, ~sum(num_campaign))): RHS of …
Run Code Online (Sandbox Code Playgroud)

r data.table tidyeval rlang

5
推荐指数
1
解决办法
403
查看次数

ggplot2带有条件构面和整洁评估的构面网格

我想创建一个生成ggplot图的函数,并为方面变量提供可选参数facet_grid()

特别是,如果可能的话,我想纳入条件逻辑里面 facet_grid。我也想使用整洁的评估框架-所以没有公式字符串!

但是,我所有的尝试都失败了。

library(tidyverse)
iris <- iris %>% add_column(idx = rep(1:2, 75))
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试失败,因为facet_grid试图找到一个名为NULL(带有反引号)的变量。

plot_iris <- function(df_in, facet_var = NULL){
  ggplot(df_in) +
    geom_point(aes(Sepal.Length, Sepal.Width)) +
    facet_grid(vars(!!enquo(facet_var)), vars(idx))
}

plot_iris(iris)

#> Error: At least one layer must contain all faceting variables: `NULL`.
#> * Plot is missing `NULL`
#> * Layer 1 is missing `NULL`
Run Code Online (Sandbox Code Playgroud)

plot_iris(iris, Species)但是,运行正常。

我的第二次尝试也失败了,但是有不同的错误消息。

plot_iris2 <- function(df_in, facet_var = NULL){
  facet_quo <- enquo(facet_var)

  ggplot(df_in) …
Run Code Online (Sandbox Code Playgroud)

r ggplot2 tidyverse tidyeval

5
推荐指数
1
解决办法
398
查看次数

卷曲Tidy评估和修改输入或其名称

本文阐述了一种新的卷曲卷曲整洁评价方法。给出了几个示例,说明了这种风格的非标准评估(NSE)的使用。

library(tidyverse)

# Example 1 --------------------------
max_by <- function(data, var, by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(maximum = max({{ var }}, na.rm = TRUE))
}
starwars %>% max_by(height)
starwars %>% max_by(height, by = gender)

# Example 2 --------------------------
summarise_by <- function(data, ..., by) {
  data %>%
    group_by({{ by }}) %>%
    summarise(...)
}

starwars %>%
  summarise_by(average = mean(height, na.rm = TRUE),
               maximum = max(height, na.rm = TRUE),
               by = gender)
Run Code Online (Sandbox Code Playgroud)

我创建了一些自己的函数,实际上这是一个更容易开发的框架,而不用担心所有的夸张和爆炸。

但是,同一篇文章说明我们还没有完全走出困境:

当您需要以某种方式修改输入或输入名称时,只需要使用引号和取消引号(带有复数形式的enquos()和!!!)。

...,但未提供示例。不抱怨,只是问是否有人可以填补空白并提供示例。由于我对Tidy的评估不流利,所以我真的不明白作者对那句话的理解(对不起)

r non-standard-evaluation tidyeval rlang

5
推荐指数
1
解决办法
330
查看次数

生成引用现有变量的动态变量

我正在尝试生成具有重要恒星的相关矩阵。采取以下数据框:

df <- tibble(stub = c(1,2,3,4),
             stub_pvalue = c(.00, .04, .07,.2))
Run Code Online (Sandbox Code Playgroud)

我想编写一个函数,如果stub_pvalue小于.01,则粘贴任何与“ ***”连接的列(例如本例中的stub),否则直接粘贴stub。就像是:

assign_stars <- function(var) {

    if (paste0(var,"_pvalue") < .01) {
      paste0(var, "***")
    } else {
      paste0(var)
    }

}

df %>% 
  mutate(col_with_stars = map_chr(col, assign_stars))
Run Code Online (Sandbox Code Playgroud)

但是,我不知道如何在var +“ _pvalue”上评估if的第一个逻辑条件。有人可以帮忙吗?

r dplyr purrr tidyverse tidyeval

5
推荐指数
1
解决办法
93
查看次数