标签: tidyeval

整洁的评估编程和ggplot2

尝试编写一个相对简单的包装器来生成一些图,但是无法弄清楚如何指定整理评估的分组变量,这些变量被指定为...一个面向变量但不通过分组区分的示例函数...

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)

r ggplot2 dplyr tidyeval rlang

12
推荐指数
1
解决办法
1055
查看次数

如何将ggplot和dplyr组合成一个函数?

考虑这个简单的例子

library(dplyr)
library(ggplot2)

dataframe <- data_frame(id = c(1,2,3,4),
                        group = c('a','b','c','c'),
                        value = c(200,400,120,300))

# A tibble: 4 x 3
     id group value
  <dbl> <chr> <dbl>
1     1     a   200
2     2     b   400
3     3     c   120
4     4     c   300
Run Code Online (Sandbox Code Playgroud)

在这里,我想编写一个将数据帧和分组变量作为输入的函数.理想情况下,在分组和聚合后,我想打印一个ggpplot图表.

这有效:

get_charts2 <- function(data, mygroup){

  quo_var <- enquo(mygroup)

  df_agg <- data %>% 
    group_by(!!quo_var) %>% 
    summarize(mean = mean(value, na.rm = TRUE),
              count = n()) %>% 
    ungroup()

  df_agg
}



> get_charts2(dataframe, group)
# A tibble: …
Run Code Online (Sandbox Code Playgroud)

r ggplot2 dplyr tidyeval

12
推荐指数
2
解决办法
957
查看次数

为什么 !!(bang-bang) 结合 as.name() 给出与 !! 不同的输出。还是 as.name() 单独?

我使用动态变量(例如ID)作为引用列名的方式,该列名将根据我当时正在处理的基因而改变。然后我使用case_wheninsidemutate创建一个新列,该列的值取决于动态列。

我认为!!(bang-bang) 是我强制对变量内容进行 eval 所需要的;但是,我没有在我的新专栏中得到预期的输出。只有!!as.name给了我期望的输出,我不完全明白为什么。有人可以解释为什么在这种情况下使用 only!!是不合适的,以及发生了!!as.name什么?

这是我制作的一个简单的可重现示例,用于演示我所体验的内容:

library(tidyverse)

ID <- "birth_year"

# Correct output
test <- starwars %>%
  mutate(FootballLeague = case_when(
    !!as.name(ID) < 10 ~ "U10",
    !!as.name(ID) >= 10 & !!as.name(ID) < 50 ~ "U50",
    !!as.name(ID) >= 50 & !!as.name(ID) < 100 ~ "U100",
    !!as.name(ID) >= 100 ~ "Senior",
    TRUE ~ "Others"
  ))

# Incorrect output
test2 <- starwars %>%
  mutate(FootballLeague = case_when(
    !!(ID) < 10 …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse tidyverse tidyeval

12
推荐指数
1
解决办法
344
查看次数

dplyr/tidyevaluation:如何将mutate中的表达式作为字符串传递?

我想编写一个有两个输入的函数:一个新变量的名称和一个数学表达式.两个参数都是字符串.

此函数应采用data.frame并添加指定的新变量,该变量应该是给定数学表达式的结果.

这是我尝试过的最小工作示例:

df <- tibble(A = 1:10, B = 1:10)
new_var <- "C"
expression <- "A + B"


example_fun <- function(new_var, expression) {
  new_var_sym <- sym(new_var)
  expression_sym <-  sym(expression)

  mutate(df, !! new_var_sym := !! expression_sym)
}

example_fun(new_var, expression)
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误:

Error in mutate_impl(.data, dots) : Binding not found: A + B.

当我在函数中包含mutate行时expr(),我得到了

mutate(df, `:=`(C, `A + B`))
Run Code Online (Sandbox Code Playgroud)

似乎周围的蜱A + B不应该存在,但我无法弄清楚如何摆脱它们.至少,enquo()quo_name()没有帮助.

r dplyr mutate tidyeval

11
推荐指数
1
解决办法
1648
查看次数

如何使用purrr循环整理eval函数?

我有以下数据集(示例):

train <- data.frame(ps_ind_06_bin = c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE),
                        ps_ind_07_bin = c(FALSE, TRUE, TRUE, FALSE, TRUE, TRUE),
                        ps_ind_08_bin = c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE),
                        ps_ind_09_log = c(1, 3, 4, 2, 3, 2))
Run Code Online (Sandbox Code Playgroud)

我有以下函数显示group_by()操作的ggplot :

get_charts1 <- function(mygroup){
  quo_var <- enquo(mygroup)
  train %>% 
    group_by(!!quo_var) %>% 
    count() %>%
    ungroup() %>%
  ggplot(aes_q(x = quo_var, y = quote(n), fill = quo_var)) + 
    geom_col() +
    theme(legend.position = "none")
    }
Run Code Online (Sandbox Code Playgroud)

我手动输入列名称时工作正常,例如:

get_charts1(ps_ind_07_bin)
Run Code Online (Sandbox Code Playgroud)

但是,我想在几个列上使用该函数,我将它放在一个向量上:

binarias <- train %>% 
             select(ends_with("bin")) %>% 
             colnames()
Run Code Online (Sandbox Code Playgroud)

使用地图并提出一些建议,我试图使用: …

r ggplot2 purrr tidyverse tidyeval

10
推荐指数
2
解决办法
808
查看次数

使用数据掩码找不到变量

library(rlang)
myquo <- quo((Temp - 32) / 1.8)
eval_tidy(myquo, data = as_data_mask(datasets::airquality)) # works
e <- as_env(datasets::airquality, parent = global_env())
eval_tidy(myquo, data = as_data_mask(list(), parent = e))   # error
Run Code Online (Sandbox Code Playgroud)

我期望Temp被发现e.我究竟做错了什么?

PS:我有R版本3.5.0并使用最新的CRAN和GitHub版本的{rlang}进行了测试.

r tidyeval

10
推荐指数
1
解决办法
88
查看次数

之间有什么区别。和.data?

我正在尝试更深入地理解使用点(“.”)dplyr和使用.data代词dplyr。我写的激发这篇文章的代码看起来像这样:

cat_table <- tibble(
  variable = vector("character"), 
  category = vector("numeric"), 
  n        = vector("numeric")
) 

for(i in c("cyl", "vs", "am")) {
  cat_stats <- mtcars %>% 
    count(.data[[i]]) %>% 
    mutate(variable = names(.)[1]) %>%
    rename(category = 1)
  
  cat_table <- bind_rows(cat_table, cat_stats)
}
Run Code Online (Sandbox Code Playgroud)
# A tibble: 7 x 3
  variable category     n
  <chr>       <dbl> <dbl>
1 cyl             4    11
2 cyl             6     7
3 cyl             8    14
4 vs              0    18
5 vs              1    14
6 am              0    19 …
Run Code Online (Sandbox Code Playgroud)

r dplyr tidyeval

10
推荐指数
1
解决办法
350
查看次数

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

R:使用字符串作为参数来改变dplyr中的动词

我正在构建一个闪亮的应用程序,需要允许用户定义用于绘图的新变量.具体来说,我想允许用户定义一个在mutate动词中使用的表达式.服务器接收表达式作为文本,我想知道如何使mutate在dplyr 0.7中执行它.我可以使用mutate_使其工作(部分),但现在已弃用.它还将新列名称定义为整个表达式而不是新变量

这是一个可重复的例子:

input_from_shiny <- "Petal.ratio = Petal.Length/Petal.Width"
iris_mutated <- iris %>% mutate_(input_from_shiny)
Run Code Online (Sandbox Code Playgroud)

这给出了以下内容

> head(iris_mutated)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Petal.ratio = Petal.Length/Petal.Width
1          5.1         3.5          1.4         0.2  setosa                                   7.00
2          4.9         3.0          1.4         0.2  setosa                                   7.00
3          4.7         3.2          1.3         0.2  setosa                                   6.50
4          4.6         3.1          1.5         0.2  setosa                                   7.50
5          5.0         3.6          1.4         0.2  setosa                                   7.00
6          5.4         3.9          1.7         0.4  setosa                                   4.25
Run Code Online (Sandbox Code Playgroud)

从技术上讲,我可以使用正则表达式从字符串中提取新的变量名并相应地重命名新列,但我想知道使用最新的dplyr版本实现它的正确方法是什么(正在阅读https://cran.r-project .org/web/packages/dplyr/vignettes/programming.html,但无法弄清楚)

r dplyr nse tidyeval

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

是否可以将多个变量传递给相同的卷曲?

我正在构建一个使用 {{ }} (卷曲卷曲或双胡子)的函数

我希望用户能够将多个变量传递到同一个 {{ }},但我不确定使用 {{ }} 是否可行。我找不到任何显示如何执行此操作的示例。

如果可能的话,你能告诉我吗,如果可能,请帮助我使下面的最小 reprex 工作?

library(tidyverse)

group_mean <- function(.data, group){
  .data %>% 
    group_by({{group}}) %>% 
    summarise_all(mean)

}

# Works
mtcars %>% 
  group_mean(group = cyl)

# Fails
mtcars %>% 
  group_mean(group = c(cyl, am)) 

Error: Column `c(cyl, am)` must be length 32 (the number of rows) or one, not 64 
Run Code Online (Sandbox Code Playgroud)

r tidyeval

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

标签 统计

r ×10

tidyeval ×10

dplyr ×7

ggplot2 ×3

tidyverse ×3

nse ×2

rlang ×2

mutate ×1

purrr ×1