标签: tidyeval

整洁评估:向函数添加参数以防止收集

我正在尝试构建一个收集(pivot_longer)数据的函数。
在大多数情况下,该函数应收集所提供数据中除一列之外的所有列,但应允许用户在所提供的数据中指定不应收集的其他列。这是用户很少会做的事情,所以参数应该默认为没有额外的列。

我认为我的函数失败了,因为它默认为NULL.

数据:

library(tidyverse)
sample_data <- tibble(
  frame = rep(seq(1:20), 2),
  ID = rep(c(1,2), each = 20),
  a = rnorm(n = 40),
  b = rnorm(n = 40),
  c = rnorm(n = 40))
Run Code Online (Sandbox Code Playgroud)

功能:

a_gather_function <- function(.data, also_dont_gather = NULL) {
  .data %>% 
  tidyr::gather(key, value, -frame, -{{also_dont_gather}})
}
Run Code Online (Sandbox Code Playgroud)

如果我为参数提供一列,则该函数有效 also_dont_gather

sample_data %>% 
  a_gather_function(also_dont_gather = ID) %>% 
  head(5)

# A tibble: 5 x 4
  frame    ID key    value
  <int> <dbl> <chr>  <dbl>
1     1     1 a     -0.626
2     2 …
Run Code Online (Sandbox Code Playgroud)

r tidyr tidyeval

2
推荐指数
1
解决办法
60
查看次数

列名称上整洁的评估映射

我自己做了如下的功能:

    emp_term_var <- function(data, colName, year = "2015") {
  
  # Terminations by year and variable in df
  colName <- enquo(colName) 
  term_test <- data %>%
    filter(year(DateofTermination) == year) %>%
    group_by(UQ(colName)) %>%
    count(UQ(colName)) %>%
    clean_names()
  return(term_test)
  
}
Run Code Online (Sandbox Code Playgroud)

我有一个包含多个列的 df,例如 Department、State、Position 等。当我想使用我编写的函数时,我将列的名称不带引号,如下所示:

emp_term_var(data = df, colName = Department, year = "2015")
Run Code Online (Sandbox Code Playgroud)

返回:

# A tibble: 5 x 2
# Groups:   department [5]
  department               n
  <chr>                <int>
1 Admin Offices            1
2 IT/IS                    4
3 Production              15
4 Sales                    1
5 Software Engineering     2 …
Run Code Online (Sandbox Code Playgroud)

r purrr tidyverse tidyeval

2
推荐指数
1
解决办法
348
查看次数

Dplyr 多个管道动态变量?

我经常这样做:

library(tidyverse)

iris %>% 
  group_by(Species) %>% 
  summarise(num_Species = n_distinct(Species)) %>% 
  mutate(perc_Species = 100 * num_Species / sum(num_Species))
Run Code Online (Sandbox Code Playgroud)

所以我想创建一个输出相同内容但具有动态命名的 num_ 和 perc_ 列的函数:

num_perc <- function(df, group_var, summary_var) {
  
}
Run Code Online (Sandbox Code Playgroud)

我发现这个资源很有用,但它没有直接解决如何以我想要的方式重用新创建的列名称。

r dplyr tidyeval

2
推荐指数
1
解决办法
191
查看次数

在 R/Tidyeval 中的 RHS 上使用类胶水结构

我花了几个小时试图在公式的 RHS 上粘上胶水,但没有任何线索。这是一个简单的表示。

meta <- function(x, var, suffix){
  x<- x %>% mutate("{{var}}_{suffix}":= 5)
  
  x<- x %>% mutate("{{var}}_{suffix}_new":= {{var}} - "{{var}}_{suffix}")
  
  
}

x<- meta(mtcars, mpg, suf)

#Should be equivalent to

x<- mtcars %>% mutate(mpg_suf:= 5)

x<- x%>% mutate(mpg_suf_new:= mpg - mpg_suf)

#N: Tried /sf/ask/4929918241/ but none of the methods in it worked, unfortunately

Run Code Online (Sandbox Code Playgroud)

元函数给我“local_error_context(dots =dots,.index = i,mask = mask)中的错误:承诺已在评估中:递归默认参数引用或早期问题?”

浏览了 SO 上搜索词的所有点击,但目前没有任何效果。

非常感谢任何见解。谢谢你!

r tidyeval

2
推荐指数
1
解决办法
90
查看次数

在 dplyr 自定义函数中将函数参数作为字符串求值

我正在编写一个自定义函数,用于输出字段的平均值和标准差。我希望 .field 参数在某些状态下以整齐的方式进行评估,并在另一个阶段作为字符串进行评估。如何将 .field 参数评估为字符串?

library(dplyr)
library(tidyr)

mean_sd <- function(.data, .field){
    .data %>% 
    summarise(
        mean = mean({{.field}}), 
        sd = sd({{.field}})
    ) %>% 
    pivot_longer(
        everything(),
        names_to = "stat",
        values_to = '.field' # I'd like this to print the value of .field
        ) %>% 
    mutate(across(is.numeric, ~round(.x, 2)))
}

mean_sd(mtcars, mpg)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

r dplyr tidyeval

2
推荐指数
1
解决办法
96
查看次数

dplyr中基于字符串的过滤-NSE

我想使用dplyr的新NSE表示法(版本> = 0.6)对filter数据进行动态处理。假设我有以下虚拟数据集:

df = data_frame(x = 1:10, y = 10:1, z = 10 * runif(10))
Run Code Online (Sandbox Code Playgroud)

如果现在我想过滤列tofilter = "x"中大于5的值,我知道可以这样做:

df %>% 
  filter((!!rlang::sym(tofilter)) >= 5)
Run Code Online (Sandbox Code Playgroud)

问题1

如果我也想动态更改过滤器的运算符(假设我有一个Shiny App,用户可以在其中动态selectInput过滤数据是否大于5,等于5或小于5的值)怎么办?

我想做的是以下事情:

op = ">="
val = 5
filt_expr = paste("x", op, val)
df %>% 
  filter(filt_expr)
Run Code Online (Sandbox Code Playgroud)

显然,这是行不通的,并且我在使用rlang定额/符号等方面有些过,但是没有找到正确的方法来“引用”我的输入。

问题2

额外的问题是,如果我想应用多个过滤器怎么办?我是否需要循环,还是可以创建一系列过滤表达式并将其一次性应用?

例如Shiny App,用户可以在其中键入他/她想要应用于数据的多个条件,以便我们可以动态更改格式列表:

filt_expr_list = list("x >= 5", "y <= 10", "z >= 2")
Run Code Online (Sandbox Code Playgroud)

并且我们要动态地全部应用它们,以便输出等效于:

df %>%
  filter(x >= 5, y <= 10, z >= 2) …
Run Code Online (Sandbox Code Playgroud)

r dplyr nse tidyverse tidyeval

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

Tidy Eval:在现状中使用'='

刚刚进入整洁的eval,我希望将它应用到我目前的一个项目中.

我知道你可以像这样定义表达式以传递给tidyverse函数,例如:

library(rlang)
library(tidyverse)

my.filter <- quo(species=='Human')
my.summary <- quo(mean(height, na.rm=T))

starwars %>%
  filter(!!my.filter) %>%
   summarise(!!my.summary)
Run Code Online (Sandbox Code Playgroud)

但是,如果我想重命名汇总列怎么办?对Avg_Ht说?如果我在quo()函数中尝试这个:

    my.summary <- quo(Avg_Ht=mean(height, na.rm=T))
Run Code Online (Sandbox Code Playgroud)

我受到了打击:

Error in quo(Avg_Ht = mean(height, na.rm = T)) : 
  unused argument (Avg_Ht = mean(height, na.rm = T))
Run Code Online (Sandbox Code Playgroud)

这里有什么帮助?

谢谢!

r dplyr tidyr tidyverse tidyeval

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

tidyeval函数和`View()`的问题

代码块#1和#2是相同的,除了行号14.代码块#1使用print()呼叫,代码块#2使用该View()呼叫.代码块#1工作正常.代码块#2给出了错误"Error in FUN(X[[i]], ...) : object 'cal.date' not found".为什么?

1

library(tidyverse)
set.seed(1)
graph.data <- tibble(cal.date = as.Date(40100:40129, origin = "1899-12-30"), 
                     random_num = rnorm(30, 8, 5))

child_function <- function(df, variable, hor.line = 6) {  
  variable <- enquo(variable)
  df <- df %>% mutate(mutation = 2 * !!variable, horizontal.line = hor.line)
}

parent_function <- function(df, date, variable, hor.line = 6) {
  date <- enquo(date)
  variable <- enquo(variable)
  df <- df %>% child_function(!!variable, hor.line) %>% print()  # LINE …
Run Code Online (Sandbox Code Playgroud)

r function dplyr tidyeval

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

如何使用列名向量作为dplyr :: group_by()的输入?

我想创建一个函数dplyr,对数据子集执行某些操作。子集由数据集中一个或多个键列的值定义。当仅使用一列来标识子集时,我的代码可以正常工作:

set.seed(1)
df <- tibble(
  g1 = c(1, 1, 2, 2, 2),
  g2 = c(1, 2, 1, 2, 1),
  a = sample(5)
)
group_key <- "g1"
aggregate <- function(df, by) {
  df %>% group_by(!!sym(by)) %>% summarize(a = mean(a))
}
aggregate(df, by = group_key)
Run Code Online (Sandbox Code Playgroud)

这将按预期工作,并返回如下内容:

# A tibble: 2 x 2
     g1     a
  <dbl> <dbl>
1     1   1.5
2     2   4  
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果我改变一切,一切都会崩溃group_key

# A tibble: 2 x 2
     g1     a
  <dbl> <dbl>
1     1   1.5
2     2 …
Run Code Online (Sandbox Code Playgroud)

eval r dplyr tidyeval

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

R自己函数中R中的动态变量引用的R准引用和tidyeval

我试图在我自己的函数中使用R中的tidyverse的准引用。我在这里已经读过这一篇文章:将参数列表传递给带有准引号的函数,以及此处的全部内容:https : //tidyeval.tidyverse.org/

但是我仍然无法正常工作。

假设我有以下数据:

dat <- data.frame(time   = runif(20),
                  group1 = rep(1:2, times = 10),
                  group2 = rep(1:2, each = 10),
                  group3 = rep(3:4, each = 10))
Run Code Online (Sandbox Code Playgroud)

我现在想做的是编写一个执行以下操作的函数:

  • 取一个数据集
  • 指定包含时间的变量(请注意,在另一个数据集中,这可能称为“小时”或“ qtime”或其他名称)
  • 指定我要对哪些组进行操作/统计

因此,我希望用户使用的功能如下:

test_function(data = dat, time_var = "time", group_vars = c("group1", "group3")) 请注意,下次我可能选择其他分组变量,或者没有选择。

假设在我要执行的功能中:

  • 计算有关时间变量的某些统计信息,例如分位数。注意:我想按我的分组变量进行拆分

这是我最近的尝试之一:

test_function <- function(data, time_var = NULL, group_vars = NULL)
{
# Note I initialize the variables with NULL, since e.g. the user might not specify a grouping 

and I …
Run Code Online (Sandbox Code Playgroud)

r tidyeval quosure

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

标签 统计

r ×10

tidyeval ×10

dplyr ×6

tidyverse ×3

tidyr ×2

eval ×1

function ×1

nse ×1

purrr ×1

quosure ×1