试图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) 我正在编写一个用于制作人口统计数据表的函数包。我有一个函数,缩写如下,我需要在其中获取几列 ( ...),并在其中添加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) 我正在创建一个工作流程,其中包含相同的管道步骤:重命名、选择依据,然后使用我在管道之前提供的名称来更改所有内容。
我已经成功使用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) 我正在一个长数据库(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) 我试图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) 我的问题与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_at与filter+相同的行across() …
“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)
如果我分别提取列,那么它适用于map2和exec
map2(sim$f, sim$params, function(fn, args) exec(fn, !!!args, n = 10))
Run Code Online (Sandbox Code Playgroud)
但是,我不能让mutate工作与map2和exec
sim %>%
mutate(sim = map2(f, params, function(fn, args) exec(fn, !!!args, n = 10)))
Run Code Online (Sandbox Code Playgroud)
我收到错误“错误:无法拼接类型闭包的对象,因为它不是向量”
有人能帮忙吗?
我正在编写一个函数来使用 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) 我试图了解 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) 我在用 !!!(拼接运算符/大爆炸运算符)用于 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)