标签: tidyeval

使用dplyr :: filter问题创建R函数

我已经查看了其他答案,但找不到下面代码的解决方案.基本上,我正在创建一个函数,inner_join即两个数据框并filter基于函数中输入的列.

问题是filter函数的一部分不起作用.但是,如果我将函数过滤掉并将其追加,它就可以工作mydiff("a") %>% filter(a.x != a.y)

任何建议都有帮助.

请注意,我是引号中的函数输入

library(dplyr)

# fake data
df1<- tibble(id = seq(4,19,2), 
             a = c("a","b","c","d","e","f","g","h"), 
             b = c(rep("foo",3), rep("bar",5)))
df2<- tibble(id = seq(10, 20, 1), 
             a = c("d","a", "e","f","k","m","g","i","h", "a", "b"),
             b = c(rep("bar", 7), rep("foo",4)))

# What I am trying to do
dplyr::inner_join(df1, df2, by = "id") %>% select(id, b.x, b.y) %>% filter(b.x!=b.y)

#> # A tibble: 1 x 3
#>      id b.x   b.y  
#>   <dbl> <chr> …
Run Code Online (Sandbox Code Playgroud)

r filter dplyr tidyeval rlang

6
推荐指数
2
解决办法
736
查看次数

如何在`mutate`中的`map`中取消引号(!!)

我正在foo使用map2和修改嵌套的数据框mutate,并且我想根据来在每个嵌套的数据框中命名一个变量foo$name。我不确定nse/ tidyeval取消引号的正确语法在这里。我的尝试:

library(tidyverse)

foo <- mtcars %>%
  group_by(gear) %>%
  nest %>%
  mutate(name = c("one", "two", "three")) %>%
  mutate(data = map2(data, name, ~
                       mutate(.x, !!(.y) := "anything")))
#> Error in quos(...): object '.y' not found
Run Code Online (Sandbox Code Playgroud)

我希望嵌套数据框中的新创建变量的名称分别为“一个”,“两个”和“三个”。

如果我对normal mutate进行普通操作df,那么我将基于普通语法使用我的尝试,name字符串在哪里:

name <- "test"
mtcars %>% mutate(!!name := "anything") # works fine
Run Code Online (Sandbox Code Playgroud)

如果成功,则以下行应返回TRUE

foo[1,2] %>% unnest %>% names %>% .[11] == "one"
Run Code Online (Sandbox Code Playgroud)

r dplyr purrr tidyeval rlang

6
推荐指数
1
解决办法
222
查看次数

使用“rlang”NSE 按多个变量进行分组

我正在尝试编写一个自定义函数,该函数使用 的rlang非标准评估来按多个变量对数据帧进行分组。

这就是我已经-

library(rlang)

# function definition
tryfn <- function(data, groups, ...) {

  # preparing data
  df <- dplyr::group_by(data, !!!rlang::enquos(groups))
  print(head(df))

  # applying some function `.f`  on df that absorbs `...`
  # .f(df, ...)
}
Run Code Online (Sandbox Code Playgroud)

这适用于单个分组变量 -

# works
tryfn(mtcars, am)

#> # A tibble: 6 x 11
#> # Groups:   am [2]
#>     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> …
Run Code Online (Sandbox Code Playgroud)

r tidyverse tidyeval rlang

6
推荐指数
1
解决办法
445
查看次数

将变量传递到tidyr::pivot_wider 的names_glue 参数中

以下是一些我们使用两个名称进行更广泛旋转的愚蠢数据:

library(tidyr)

df <- data.frame(
    food = c('banana','banana','banana','banana','cheese','cheese','cheese','cheese'),
    binary = c(rep(c('yes','no'), 4)),
    car = c('toyota','subaru','mazda','skoda','toyota','subaru','mazda','skoda'),
    fun = c(2,4,3,6,2,4,2,3))

df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(car, binary),
        values_from = fun)
Run Code Online (Sandbox Code Playgroud)

如果我们想更改新变量名称的格式,例如从toyota_yesyes_toyota,我们使用names_glue参数:

df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(car, binary),
        names_glue = "{binary}_{car}",
        values_from = fun)
Run Code Online (Sandbox Code Playgroud)

我面临的问题是找到正确的语法将变量名称传递给参数names_glue。将变量传递给 很容易names_from,例如:

var1 <- 'car'
var2 <- 'binary'
df %>%
    pivot_wider(
        id_cols = food,
        names_from = c(var1, var2),
        values_from = fun)
Run Code Online (Sandbox Code Playgroud)

但我们不能直接这样做 …

r tidyr tidyeval r-glue

6
推荐指数
1
解决办法
6367
查看次数

使用dplyr :: filter的tidyeval方法是什么?

使用调用下面的函数foo(c("b"))。输出显示为内联。

什么是正确的写作方式df %>% filter(!!x > (!!x))

我提供了一个使用mutatetidyeval风格与进行对比的示例filter

foo <- function(variables) {

  x <- rlang::sym(variables[[1]])

  print(x)
  #> b

  print(typeof(x))
  #> [1] "symbol"

  df <- data_frame(a = 1, b = 2)

  print(df %>% mutate(!!x := 100 + !!x))

  #> # A tibble: 1 x 2
  #>         a     b
  #>       <dbl> <dbl>
  #>   1     1   102  

  print(df %>% filter(!!x  > (!!x)))

  #> Error in !x : invalid argument type

  print(df %>% filter(magrittr::is_greater_than(!!x, !!x)))

  #> # …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyeval

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

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
查看次数

Tidy Eval:不可能在嵌套函数中使用 {{var}}?

我试图tidyr::complete在我的函数中使用,同时使用{{}}. 这工作正常,但是,当我添加一个嵌套函数来组合两个变量时,我得到一个错误。请参阅下面的最小示例。

library(tidyverse)
library(rlang)

df <- tibble(
  group1 = c(1:2, 1),
  group2 = c("c", "c", "c"),
  item_id = c(1:2, 2),
  item_name = c("a", "b", "b"),
  value1 = 1:3,
  value2 = 4:6
)

my_complete <- function(data, var1, var2, var3, var4, var5, var6){
  data %>%
    tidyr::complete({{var1}}, {{var3}})
}

my_complete(df, var1 = group1, var2 = group2, var3 = item_id, var4 = item_name, var5 = value1, var6 = value2)
Run Code Online (Sandbox Code Playgroud)

这有效,输出为:

# A tibble: 4 x 6
  group1 item_id group2 item_name …
Run Code Online (Sandbox Code Playgroud)

r metaprogramming tidyverse tidyeval rlang

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

使用 dplyr 进行问题编程——列绝对是一个被选取为公式的向量

我正在编写一个函数来使用 highcharter 重现几个图表,这些图表都将具有类似的格式(和其他内容)。如果名称发生更改,或者如果我想做一些不同的事情并且我正在接受这些参数,我希望能够选择数据集的不同列{{ }}。但是后来我收到了这个奇怪的错误:

Error: Problem with `mutate()` input `x`.
x Input `x` must be a vector, not a `formula` object.
i Input `x` is `~Year`.
Run Code Online (Sandbox Code Playgroud)

这是我的(最小可重现)代码:

library(dplyr)
library(highcharter)

plot_high_chart <- function(.data,
                            chart_type = "column",
                            x_value = Year,
                            y_value = total,
                            group_value = service) {
  .data %>% 
  hchart(chart_type, hcaes(x = {{x_value}}, y = {{y_value}}, group = {{group_value}}))
}

data %>% plot_high_chart()
Run Code Online (Sandbox Code Playgroud)

这是dput数据的结果:

structure(list(Year = c(2016, 2017, 2017, 2018, 2018, 2018), 
    service = structure(c(10L, 3L, …
Run Code Online (Sandbox Code Playgroud)

r dplyr r-highcharter tidyeval rlang

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

如何创建一个函数来改变具有变量名和“_pct”的新列?

mtcars作为例子使用。我想编写一个创建函数countpct列,如下面-

library(tidyverse)

mtcars %>% 
  group_by(cyl) %>% 
  summarise(count = n()) %>% 
  ungroup() %>% 
  mutate(cyl_pct = count/sum(count))
Run Code Online (Sandbox Code Playgroud)

这会产生输出 -

# A tibble: 3 x 3
    cyl count mpg_pct
  <dbl> <int>   <dbl>
1     4    11   0.344
2     6     7   0.219
3     8    14   0.438
Run Code Online (Sandbox Code Playgroud)

但是,我想创建一个函数,在该函数中我可以将group_by列指定为任何列,并且该mutate列将命名groub_by_pct. 因此,如果我想使用disp,disp将是我的group_by变量,并且该函数将改变一disp_pct列。

r tidyeval

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