dplyr::case_when当我使用而不是if参考本文时,我注意到下面的这种行为。如果第二个分支的输出是显式字符串,则它会按预期工作,但如果x指定了其本身,则结果会发生变化。
为什么只case_when给出不同的结果?
x <- character(0)
dplyr::case_when(rlang::is_empty(x) ~ "Empty", !rlang::is_empty(x) ~ "Not empty")
#> [1] "Empty"
dplyr::case_when(rlang::is_empty(x) ~ "Empty", !rlang::is_empty(x) ~ x)
#> character(0)
if (rlang::is_empty(x)) "Empty" else if (!rlang::is_empty(x)) "Not empty"
#> [1] "Empty"
if (rlang::is_empty(x)) "Empty" else if (!rlang::is_empty(x)) x
#> [1] "Empty"
ifelse(rlang::is_empty(x), "Empty", "Not empty")
#> [1] "Empty"
ifelse(rlang::is_empty(x), "Empty", x)
#> [1] "Empty"
Run Code Online (Sandbox Code Playgroud)
由reprex 包于 2022 年 8 月 16 日创建(v2.0.1)
前言
我通常dplyr在我的包中使用.在此之前0.7.0,我使用dplyr动词的强调版本来避免在注释期间R CMD CHECK.例如,代码:
x <- tibble::tibble(v = 1:3, w = 2)
y <- dplyr::filter(x, v > w)
Run Code Online (Sandbox Code Playgroud)
本来会产生这样的R CMD CHECK说明:
* checking R code for possible problems ... NOTE
no visible binding for global variable ‘v’
Run Code Online (Sandbox Code Playgroud)
相比之下,使用标准评估版:
y <- dplyr::filter_(x, ~v > w)
Run Code Online (Sandbox Code Playgroud)
没有发出这样的说明.
但是,使用dplyr编程dplyr 0.7.0的插图表示在包中包含函数的适当语法(以避免注释)是:dplyr
y <- dplyr::filter(x, .data$v > .data$w)
Run Code Online (Sandbox Code Playgroud)
因此,新闻文件说"不再需要每个主要动词的强调版本,因此这些功能已被弃用(但为了向后兼容性而保持不变)."
题
小插图说上面的新语法不会产生R CMD checkNOTES,"只要你还导入rlang::.data了@importFrom rlang …
与此问题相关.
我想构建一个自定义管道%W>%,可以使一个操作的警告静音
library(magrittr)
data.frame(a= c(1,-1)) %W>% mutate(a=sqrt(a)) %>% cos
Run Code Online (Sandbox Code Playgroud)
将相当于:
w <- options()$warn
data.frame(a= c(1,-1)) %T>% {options(warn=-1)} %>%
mutate(a=sqrt(a)) %T>% {options(warn=w)} %>%
cos
Run Code Online (Sandbox Code Playgroud)
这两次尝试不起作用:
`%W>%` <- function(lhs,rhs){
w <- options()$warn
on.exit(options(warn=w))
options(warn=-1)
lhs %>% rhs
}
`%W>%` <- function(lhs,rhs){
lhs <- quo(lhs)
rhs <- quo(rhs)
w <- options()$warn
on.exit(options(warn=w))
options(warn=-1)
(!!lhs) %>% (!!rhs)
}
Run Code Online (Sandbox Code Playgroud)
我怎么能把rlang它变成有效的东西呢?
考虑一个小标题,其中每一列都是可以采用许多值的字符向量-假设是“ A”到“ F”。
library(tidyverse)
sample_df <- tibble(q1 = c("A", "B", "C"), q2 = c("B", "B", "A"))
Run Code Online (Sandbox Code Playgroud)
我希望创建一个函数,该函数将列名作为参数,并重新编码该列,以使任何答案“ A”都变为NA,否则将按原样返回df。以这种方式设计它的原因是适合于使用给定列执行一系列操作的更广泛的管道。
有很多方法可以做到这一点。但是我有兴趣了解最佳的惯用tidy_eval / tidyverse方法是什么。首先,问题名称必须位于变异动词的左侧,因此我们适当地使用!!and :=运算符。但是,那该放在右边呢?
fix_question <- function(df, question) {
df %>% mutate(!!question := recode(... something goes here...))
}
fix_question(sample_df, "q1") # should produce a tibble whose first column is (NA, "B", "C")
Run Code Online (Sandbox Code Playgroud)
我最初的想法是,这将起作用:
df %>% mutate(!!question := recode(!!question, "A" = NA_character_))
Run Code Online (Sandbox Code Playgroud)
但是,当然,函数内部的爆炸只是返回文字字符串(例如“ q1”)。我最终采取了一种感觉很拙劣的方法,即使用基本R [[运算符并依靠.dplyr 的构造来在右侧引用数据,并且它起作用了,因此从某种意义上说,我已经解决了我的根本问题:
df %>% mutate(!!question := recode(.[[question]], "A" = NA_character_))
Run Code Online (Sandbox Code Playgroud)
我有兴趣从精通tidyeval的人那里获得反馈,以了解是否有更惯用的方法来执行此操作,希望看到一个可行的示例可以增强我对tidyeval函数集的更一般的理解。有什么想法吗?
尝试编写一个相对简单的包装器来生成一些图,但是无法弄清楚如何指定整理评估的分组变量,这些变量被指定为...一个面向变量但不通过分组区分的示例函数...
my_plot <- function(df = starwars,
select = c(height, mass),
...){
results <- list()
## Tidyeval arguments
quo_select <- enquo(select)
quo_group <- quos(...)
## Filter, reshape and plot
results$df <- df %>%
dplyr::filter(!is.na(!!!quo_group)) %>%
dplyr::select(!!quo_select, !!!quo_group) %>%
gather(key = variable, value = value, !!!quo_select) %>%
## Specify what to plot
ggplot(aes(value)) +
geom_histogram(stat = 'count') +
facet_wrap(~variable, scales = 'free', strip.position = 'bottom')
return(results)
}
## Plot height and mass as facets but colour histograms by hair_color
my_plot(df …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个用于创建棒棒糖图的函数ggplot2。我想将所有参数传递...到aes()inside geom_point()。但是,我想排除size传递到aes()内部的参数geom_segment()(如果您查看a()下面的输出,原因很明显)。因此,我捕获...usingrlang::enquos()而不是按原样传递它。在功能上a(),我传递dots到aes()内ggplot()这个作品没有问题。但在功能上b()我得到了错误Can't use '!!!' at top level.
我被困在这一点上,并感谢任何输入来解决这个问题。
library(ggplot2)
data("mtcars")
d <- dplyr::count(mtcars, cyl, am)
a <- function(data, x, y, ...) {
x <- rlang::enquo(x)
y <- rlang::enquo(y)
dots <- rlang::enquos(...)
ggplot(data, aes(!!x, !!y, !!!dots)) +
geom_segment(aes(y = 0, xend = !!x, yend = !!y)) +
geom_point() …Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个函数tidyverse/dplyr,我想最终使用lapply(或map).(我一直在努力回答这个问题,但发现了一个有趣的结果/死胡同.请不要将其标记为重复 - 这个问题是你在那里看到的答案的延伸/背离.)
是否有
1)获取引用变量列表以在dplyr函数内工作
(并且不使用已弃用的SE_函数)的方法, 或者是
2)某种方式通过一个lapply或多个方式提供一个未加引号的字符串列表map
我使用Programming in Dplyr小插图来构建我认为最符合当前使用NSE标准的功能.
sample_data <-
read.table(text = "REVENUEID AMOUNT YEAR REPORT_CODE PAYMENT_METHOD INBOUND_CHANNEL AMOUNT_CAT
1 rev-24985629 30 FY18 S Check Mail 25,50
2 rev-22812413 1 FY16 Q Other Canvassing 0.01,10
3 rev-23508794 100 FY17 Q Credit_card Web 100,250
4 rev-23506121 300 FY17 S Credit_card Mail 250,500
5 rev-23550444 100 FY17 S Credit_card Web 100,250
6 rev-21508672 …Run Code Online (Sandbox Code Playgroud) 我有一个函数可以生成不需要的警告,但保留该值。
f <- function(a) {
if (a > 1) {
warning("an uninformative warning")
}
a
}
g1 <- function(b) {
withCallingHandlers(
x <-f(b),
warning = function(w) {
warning("A more informative warning")
})
x
}
g1(2)
#> Warning in (function (w) : A more informative warning
#> Warning in f(b): an uninformative warning
#> [1] 2
Run Code Online (Sandbox Code Playgroud)
创建于 2023 年 12 月 12 日,使用reprex v2.0.2
不幸的是,这会出现 2 个警告。
tryCatch()不保留 x 。和withCallingHandlers(),两个警告都会被抛出。
嗨跟随dplyr编程我注意到可以使用quo_name添加名称.我想知道如何为多列执行此操作,例如.像quos_name的种类.例如:
my_mutate <- function(df, expr) {
expr <- enquo(expr)
mean_name <- paste0("mean_", quo_name(expr))
sum_name <- paste0("sum_", quo_name(expr))
mutate(df,
!!mean_name := mean(!!expr),
!!sum_name := sum(!!expr)
)
}
Run Code Online (Sandbox Code Playgroud)
变
my_mutate <- function(df, ...) {
exprs <-quos(...)
mean_names <- paste0("mean_", quos_name(exprs))
sum_names <- paste0("sum_", quos_name(exprs))
mutate(df,
!!!mean_names := mean(!!!exprs),
!!!sum_names := sum(!!!exprs)
)
}
Run Code Online (Sandbox Code Playgroud)
即.为...中指定的所有列添加mean和sum列,当然这仅作为示例,并且quos_names不存在.如果有办法,这将是非常有帮助的.
我知道有可能在data.table中做这样的事情DT[,(Col_names):=lapply(Cols,mean)](这段代码不起作用,但我之前做过类似的事情).
“!!”是什么意思 在 R 中做,为什么要使用它?
具体来说,我正在查看一个包含短语a = !!sym("x")where "x"is a string的函数
。我认为sym通过将字符串转换为对象来工作,因此a = sym("x")将设置为a等于 object x。有什么!!用?我读到它没有引用它后面的任何内容,但我认为sym它本身没有引用字符串?
我还看到!!与其他功能一起使用。它在做什么?