标签: rlang

有什么用!!运算符 mean 在 R 中,尤其是在上下文中 !!sym("x")

“!!”是什么意思 在 R 中做,为什么要使用它?

具体来说,我正在查看一个包含短语a = !!sym("x")where "x"is a string的函数 。我认为sym通过将字符串转换为对象来工作,因此a = sym("x")将设置为a等于 object x。有什么!!用?我读到它没有引用它后面的任何内容,但我认为sym它本身没有引用字符串?

我还看到!!与其他功能一起使用。它在做什么?

r operators dplyr rlang

9
推荐指数
1
解决办法
3418
查看次数

如何使用quosures将命名向量传递给dplyr :: select?

使用旧select_()函数,我可以将命名向量传递给select并立即更改位置和列名:

my_data  <- data_frame(foo = 0:10, bar = 10:20, meh = 20:30)
my_newnames  <-  c("newbar" = "bar", "newfoo" = "foo")

move_stuff  <- function(df, newnames) {
    select_(df, .dots = newnames)
}

move_stuff(my_data,  newnames = my_newnames) )

# this is the desired output
# A tibble: 4 x 2
  newbar  newfoo
   <int>   <int>
1     10       0
2     11       1
3     12       2
4     13       3
Run Code Online (Sandbox Code Playgroud)

我尝试使用quosures和拼接做类似的事情 - 选择列效果很好,但是矢量的名称(因此同时重命名列)似乎被忽略了.以下两个都返回数据框,列中包含名称barfoo,但不是newbarnewfoo:

move_stuff2  <- function(df, newnames) …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse rlang

8
推荐指数
1
解决办法
1175
查看次数

在dplyr 0.7.0+中正确使用dplyr :: select,使用字符向量选择列

假设我们有一个cols_to_select包含我们想要从数据帧中选择的列的字符向量df,例如

df <- tibble::data_frame(a=1:3, b=1:3, c=1:3, d=1:3, e=1:3)
cols_to_select <- c("b", "d")
Run Code Online (Sandbox Code Playgroud)

假设我们也想使用dplyr::select它,因为它是使用的操作的一部分,%>%因此使用select使代码易于阅读.

似乎有很多方法可以实现,但有些方法比其他方法更强大.请你告诉我哪个是"正确的"版本,为什么?或许还有另一种更好的方法?

dplyr::select(df, cols_to_select) #Fails if 'cols_to_select' happens to be the name of a column in df 
dplyr::select(df, !!cols_to_select) # i.e. using UQ()
dplyr::select(df, !!!cols_to_select) # i.e. using UQS()

cols_to_select_syms <- rlang::syms(c("b", "d"))  #See [here](https://stackoverflow.com/questions/44656993/how-to-pass-a-named-vector-to-dplyrselect-using-quosures/44657171#44657171)
dplyr::select(df, !!!cols_to_select_syms)
Run Code Online (Sandbox Code Playgroud)

ps我意识到这可以简单地在基础R中实现 df[,cols_to_select]

r dplyr tidyverse tidyeval rlang

8
推荐指数
1
解决办法
625
查看次数

使用dplyr进行功能编程

通过使用dplyr在函数中使用非标准求值,寻找一种更有效/更优雅的方法将多个参数传递给组.我不想使用...运算符,而是单独指定函数.

我的具体用例是一个函数,它接受数据框并创建一个语法更简单的ggplot对象.这是我想用我的函数自动化的代码示例:

# create data frame
my_df <- data.frame(month = sample(1:12, 1000, replace = T),
                    category = sample(head(letters, 3), 1000, replace = T),
                    approved = as.numeric(runif(1000) < 0.5))

my_df$converted <- my_df$approved * as.numeric(runif(1000) < 0.5)

my_df %>%
  group_by(month, category) %>%
  summarize(conversion_rate = sum(converted) / sum(approved)) %>%
  ggplot + geom_line(aes(x = month, y = conversion_rate, group = category, 
  color = category))
Run Code Online (Sandbox Code Playgroud)

我想将group_by,summarize,ggplot和geom_line组合成一个简单的函数,我可以提供x,y和group,并让它执行所有脏工作.这就是我的工作:

# create the function that does the grouping and plotting
plot_lines <- function(df, x, y, group) {

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

dsl r ggplot2 dplyr rlang

8
推荐指数
2
解决办法
547
查看次数

什么时候使用 rlang::ensym() 而不是 rlang::sym()?

我可以从文档中看到rlang::enquo()rlang::quo()在不同的上下文中使用。因此,我rlang::enysm()最近在函数声明中使用了(见下文)。然而,包裹在另一个 SE 函数调用中,我得到了一个意外错误,我猜这与惰性求值有关(如果我force(x)在 中,它就会消失f_enysm())。但似乎我也可以通过简单地使用sym(x)而不是ensym(x)因为x是一个不传达任何关于环境的信息(而不是quosures)的字符串来解决这个问题。

那安全吗?

如果是,我不知道什么时候应该更喜欢ensym()sym并且建议的用途似乎与quo()/ enquo()expr()/enexpr()等使用的术语不一致。

library(rlang)
f_ensym <- function(data, x, fun) {
  x <- fun(x)
  head(dplyr::arrange(data, !!x))
}
f_ensym(mtcars, "cyl", sym)
#>    mpg cyl  disp hp drat    wt  qsec vs am gear carb
#> 1 22.8   4 108.0 93 3.85 2.320 18.61  1  1    4    1
#> 2 24.4   4 146.7 …
Run Code Online (Sandbox Code Playgroud)

r tidyeval rlang

8
推荐指数
1
解决办法
1333
查看次数

在dplyr :: funs的命名参数中,我可以引用其他参数的名称吗?

考虑以下:

library(tidyverse)

df <- tibble(x = rnorm(100), y = rnorm(100, 10, 2), z = x * y)

df %>% 
mutate_all(funs(avg = mean(.), dev = sd(.), scaled = (. - mean(.)) / sd(.)))
Run Code Online (Sandbox Code Playgroud)

有没有办法通过引用和列来避免调用meansd两次.我想到的是类似的东西avgdev

df %>% 
mutate_all(funs(avg = mean(.), dev = sd(.), scaled = (. - avg) / dev))
Run Code Online (Sandbox Code Playgroud)

显然,这是行不通的,因为没有列avgdev,但是x_avg,x_dev,y_avg,y_dev,等.

有一个好办法,内部funs使用rlang的工具以编程方式创建这些列引用,这样我可以参考由以前命名的参数创建的列funs(当.x,我将引用x_mean和 …

r dplyr rlang

8
推荐指数
2
解决办法
91
查看次数

dplyr tidyr – 如何使用动态条件生成 case_when?

有没有办法来动态/编程产生case_when的条件dplyr有不同的列名和/或不同数量的条件是什么?我有一个交互式脚本,我正在尝试将其转换为函数。case_when语句中有很多重复的代码,我想知道它是否可以以某种方式自动化,而无需一次又一次地从头开始编写所有内容。

这是一个虚拟数据集:

test_df = tibble(low_A=c(5, 15, NA),
                 low_TOT=c(NA, 10, NA),
                 low_B=c(20, 25, 30),
                 high_A=c(NA, NA, 10),
                 high_TOT=c(NA, 40, NA),
                 high_B=c(60, 20, NA))

expected_df = tibble(low_A=c(5, 15, NA),
                     low_TOT=c(NA, 10, NA),
                     low_B=c(20, 25, 30),
                     ans_low=c(5, 10, 30),
                     high_A=c(NA, NA, 10),
                     high_TOT=c(NA, 40, NA),
                     high_B=c(60, 20, NA),
                     ans_high=c(60, 40, 10))

> expected_df
# A tibble: 3 x 8
  low_A low_TOT low_B ans_low high_A high_TOT high_B ans_high
  <dbl>   <dbl> <dbl>   <dbl>  <dbl>    <dbl>  <dbl>    <dbl>
1     5 …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyr rlang

8
推荐指数
3
解决办法
439
查看次数

如何检测rlang中的空状态?

f <- function(x) enquo(x)

e <- f()
#<quosure: empty>
#~
Run Code Online (Sandbox Code Playgroud)

这些都不起作用:

> is_empty(e)
[1] FALSE
> is_missing(e)
[1] FALSE
> is_false(e)
[1] FALSE
> is_quosure(e)
[1] TRUE
Run Code Online (Sandbox Code Playgroud)

r tidyverse rlang

7
推荐指数
1
解决办法
561
查看次数

基于quosure命名新变量

我正在尝试编写一个自定义函数,它将根据预定义变量向量(例如vector_heavy)的值计算新变量,然后根据提供给函数的参数(例如,custom_name)命名新变量.

这个变量命名是我的技能失败的地方.任何帮助是极大的赞赏.

library(tidyverse)

vector_heavy <- quos(disp, wt, cyl)

cv_compute <- function(data, cv_name, cv_vector){
  cv_name <- enquo(cv_name)
  data %>% 
    rowwise() %>% 
    mutate(!!cv_name = mean(c(!!!cv_vector), na.rm = TRUE)) %>% 
    ungroup()
}

d <- cv_compute(mtcars, cv_name = custom_name, cv_vector = vector_heavy)
Run Code Online (Sandbox Code Playgroud)

我的错误消息是:

Error: unexpected '=' in:
"    rowwise() %>% 
    mutate(!!cv_name ="
Run Code Online (Sandbox Code Playgroud)

删除!!之前cv_namemutate()将导致一个函数计算一个字面命名的新变量cv_name,并忽略custom_name我作为参数包含的内容.

cv_compute <- function(data, cv_name, cv_vector){
  cv_name <- enquo(cv_name)
  data %>% 
    rowwise() %>% 
    mutate(cv_name = mean(c(!!!cv_vector), na.rm = TRUE)) %>% 
    ungroup() 
} …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyverse rlang

7
推荐指数
1
解决办法
407
查看次数

将quosure转换为R中的字符串

我一直在使用dplyr的quosures:

library(dplyr)
library(ggplot2)

thing <- quo(clarity)
diamonds %>% select(!!thing)
print(paste("looking at", thing))
Run Code Online (Sandbox Code Playgroud)

[1]"看着〜""看清晰度"

我真的想打印出放入现状的字符串值,但只能得到以下内容:

print(thing)
Run Code Online (Sandbox Code Playgroud)

<quosure:global>

〜清晰度

print(thing[2])
Run Code Online (Sandbox Code Playgroud)

明晰()

substr(thing[2],1, nchar(thing[2]))
Run Code Online (Sandbox Code Playgroud)

[1]"清晰度"

有没有更简单的方法来"取消引用"quo()?

r dplyr rlang

7
推荐指数
3
解决办法
3070
查看次数

标签 统计

r ×10

rlang ×10

dplyr ×8

tidyverse ×3

tidyeval ×2

dsl ×1

ggplot2 ×1

nse ×1

operators ×1

tidyr ×1