我正在尝试构建一个收集(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) 我自己做了如下的功能:
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) 我经常这样做:
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)
我发现这个资源很有用,但它没有直接解决如何以我想要的方式重用新创建的列名称。
我花了几个小时试图在公式的 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 上搜索词的所有点击,但目前没有任何效果。
非常感谢任何见解。谢谢你!
我正在编写一个自定义函数,用于输出字段的平均值和标准差。我希望 .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)
我想使用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) 刚刚进入整洁的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)
这里有什么帮助?
谢谢!
代码块#1和#2是相同的,除了行号14.代码块#1使用print()呼叫,代码块#2使用该View()呼叫.代码块#1工作正常.代码块#2给出了错误"Error in FUN(X[[i]], ...) : object 'cal.date' not found".为什么?
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) 我想创建一个函数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) 我试图在我自己的函数中使用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)
我现在想做的是编写一个执行以下操作的函数:
因此,我希望用户使用的功能如下:
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)