标签: rlang

do.call() 和 tidy 评估

试图do.call()在整洁评估的背景下工作:

library(rlang)
library(dplyr)

data <- tibble(item_name = c("apple", "bmw", "bmw"))

mutate(data, category = case_when(item_name == "apple" ~ "fruit",
                                  item_name == "bmw" ~ "car"))

# # A tibble: 3 x 2
#   item_name category
#   <chr>     <chr>   
# 1 apple     fruit   
# 2 bmw       car     
# 3 bmw       car 
Run Code Online (Sandbox Code Playgroud)

有什么不同:

category_fn <- function(df, ...){
  # browser()
  cat1 <- quos(...)
  mutate(df, category = case_when(!!! cat1))
}

category_fn(df = data, item_name == "apple" ~ "fruit",
                       item_name == "bmw" ~ "car")

# …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse rlang

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

rlang:在 NSE 函数中使用冒号快捷方式从...获取名称

我正在编写一个用于制作人口统计数据表的函数包。我有一个函数,缩写如下,我需要在其中获取几列 ( ...),并在其中添加gather一个数据框。诀窍是我想保持这些列的名称按顺序排列,因为我需要在收集后按该顺序放置一列。在本例中,这些列是estimate, moe, share, sharemoe

library(tidyverse)
library(rlang)

race <- structure(list(region = c("New Haven", "New Haven", "New Haven", "New Haven", "Outer Ring", "Outer Ring", "Outer Ring", "Outer Ring"), 
    variable = c("white", "black", "asian", "latino", "white", "black", "asian", "latino"), 
    estimate = c(40164, 42970, 6042, 37231, 164150, 3471, 9565, 8518), 
    moe = c(1395, 1383, 697, 1688, 1603, 677, 896, 1052), 
    share = c(0.308, 0.33, 0.046, 0.286, 0.87, 0.018, 0.051, 0.045), 
    sharemoe = c(0.011, 0.011, …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse rlang

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

如何将使用 enquo() 创建的动态变量名称传递给 dplyr 的 mutate 进行评估?

我正在创建一个工作流程,其中包含相同的管道步骤:重命名、选择依据,然后使用我在管道之前提供的名称来更改所有内容。

我已经成功使用enquo()and !!(bang bang) 重命名为我想要的字符串,然后再次选择它,但是当我到达 mutate 步骤时,它要么重复文本字符串作为列值,要么不会计算。

我重新创建了下面的代码:

#Testing rename, select, and mutate use cases for enquo()

#Load packages
library(dplyr)
library(rlang)
library(magrittr)

#Create name I want to pass
new_var <- quo("new_name")

#Create Test Data
t1 <- tibble(Year = c(2000:2004),
             old_name = c(NA, 1, 1, 1, NA))
Run Code Online (Sandbox Code Playgroud)

quo_name()我可以用和 重命名该列:=

t1 %>% 
  rename( !! quo_name(new_var) := old_name)
Run Code Online (Sandbox Code Playgroud)

我可以使用它来选择!!

t1 %>% 
  rename( !! quo_name(new_var) := old_name) %>% 
  select(Year, !!new_var)
Run Code Online (Sandbox Code Playgroud)

但我无法在 mutate 中调用该列并使用这些值

t1 %>% 
  rename( !! quo_name(new_var) …
Run Code Online (Sandbox Code Playgroud)

r dplyr rlang quosure

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

Tidyverse、Rlang 和 tidyeval:Bang bang (!!) 在函数内部失败,但它似乎无需引用即可工作

我正在一个长数据库(full_database)上运行一个函数,该数据库有两个主要组,我需要在每个组的多个子集上执行各种线性模型。

然后,我将 R^2、调整后的 R^2 和 p.value 提取到数据框中,其中每一行对应于一次比较。由于有 30 种不同的情况,我有另一个小标题,其中列出了函数参数所在的所有可能性( possibility )。

原始函数的脚本是:

database_correlation <-  function(id, group) {

    require(dplyr)
    require(tidyr)
    require(rlang)

    id_name <- quo_name(id)
    id_var <- enquo(id)
    group_name <- quo_name(group)
    group_var <- enquo(group)

    corr_db <- full_database %>%
      filter(numid==!!id_name) %>%
      filter(major_group==!!group_name) %>%
      droplevels()

    correlation <- summary(lm(yvar~xvar, corr_db))

    id.x <- as.character(!!id_var) #Gives out an error: "invalid argument type"
    group.x <- as.character(!!group_var) #Gives out an error: "invalid argument type"
    r_squared <- correlation$r.squared
    r_squared_adj <- correlation$adj.r.squared
    p_value <- correlation$coefficients[2,4]

    data.frame(id.x, group.x, r_squared, r_squared_adj, …
Run Code Online (Sandbox Code Playgroud)

r tidyr tidyeval rlang

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

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

卷曲整洁的评估编程,具有多个输入和跨列的自定义函数

我的问题与this 问题类似,但我需要跨列应用更复杂的函数,并且我不知道如何将 Lionel 建议的解决方案应用到具有作用域动词 likefilter_at()filter()+across()等价物的自定义函数。{{{}}}看起来并没有引入“superstache”/运算符。

这是我想要做的一个非编程示例(不使用 NSE):

library(dplyr)
library(magrittr)

foo <- tibble(group = c(1,1,2,2,3,3),
              a = c(1,1,0,1,2,2),
              b = c(1,1,2,2,0,1))

foo %>%
  group_by(group) %>%
  filter_at(vars(a,b), any_vars(n_distinct(.) != 1)) %>%
  ungroup
#> # A tibble: 4 x 3
#>   group     a     b
#>   <dbl> <dbl> <dbl>
#> 1     2     0     2
#> 2     2     1     2
#> 3     3     2     0
#> 4     3     2     1
Run Code Online (Sandbox Code Playgroud)

我还没有找到filter_atfilter+相同的行across() …

r dplyr non-standard-evaluation tidyeval rlang

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

将 mutate 与 map2 和 exec 一起使用,而不是 invoke_map

“R for Data Science”中的这个例子使用了invoke_map现在已停用。

sim <- tribble(
  ~f, ~params,
  "runif", list(min = -1, max = 1),
  "rnorm", list(sd = 5),
  "rpois", list(lambda = 10)
)

sim %>% 
  mutate(sim = invoke_map(f, params, n = 10))
Run Code Online (Sandbox Code Playgroud)

如果我分别提取列,那么它适用于map2exec

map2(sim$f, sim$params, function(fn, args) exec(fn, !!!args, n = 10))
Run Code Online (Sandbox Code Playgroud)

但是,我不能让mutate工作与map2exec

sim %>% 
  mutate(sim = map2(f, params, function(fn, args) exec(fn, !!!args, n = 10)))
Run Code Online (Sandbox Code Playgroud)

我收到错误“错误:无法拼接类型闭包的对象,因为它不是向量”

有人能帮忙吗?

r dplyr purrr tidyverse rlang

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

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

R:Tidyverse 选择语义 tidyselect::eval_select 将数字附加到重复项

我试图了解 tidyverse 设计以及如何使用它进行编程有一段时间了。我试图编写一个使用 tidyselect 语义的函数,我发现tidyselect::eval_select将数字附加到 lhs 表达式。看到这个语义用于列重命名,这并不奇怪。不幸的是,我用于构建数据结构的函数不需要这种行为,它需要表达式的 lhs 中提供的常规名称(根据需要重复多次)。我还没有设法找出这种行为的来源;它似乎是一个,make.unique但我找不到它的实现位置。如果你知道,我很想学习,如果没有,解决我的问题不应该依赖于它。我想要的只是 lhs 名称没有附加数字,如示例所示:

library(tidyverse)

# Data
data <- mtcars[, 8:11]

# Example
data %>%
  tidyselect::eval_select(rlang::expr(c(foo = 1, bar = c(2:4), foobar = c(1, "am", "gear", "carb"))), .)
#>     foo    bar1    bar2    bar3 foobar1 foobar2 foobar3 foobar4 
#>       1       2       3       4       1       2       3       4

# Function
test <- function(.data, ...) {
  loc <- tidyselect::eval_select(rlang::expr(c(...)), .data)
  names <- names(.data)
  list(names(loc), names[loc])
}

data %>%
  test(foo = 1, bar …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyverse rlang tidyselect

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

!!! ggplot2 geom_point() 函数的(拼接运算符)

我在用 !!!(拼接运算符/大爆炸运算符)用于 ggplot2::geom_point() 函数,并且失败。有人能指出这段代码有什么问题吗?以下代码尝试从字符向量执行 ggplot2 函数。

library(rlang)
library(ggplot2)

data(mtcars)
data = mtcars

assoc = c( "cyl" , "hp" )
names(assoc) = c("x", "y")
assoc_lang = rlang::parse_exprs(assoc)
gg = ggplot2::ggplot(data, ggplot2::aes( ,, !!! assoc_lang )) # This works

params = c( "10", "\"black\"" )
names(params) = c("size", "colour" )
params_lang = rlang::parse_exprs(params)
gg = gg + ggplot2::geom_point( !!! params_lang ) # This fails

plot(gg)
Run Code Online (Sandbox Code Playgroud)
  • 输出
Error in !params_lang : invalid argument type
Calls: <Anonymous> -> layer
Execution halted
Run Code Online (Sandbox Code Playgroud)

(注意)以下代码是交互式方式的等效代码,它显示了我想要在上面的代码中执行的操作。

library(ggplot2)

data(mtcars) …
Run Code Online (Sandbox Code Playgroud)

r ggplot2 rlang

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