【发布时间】:2023-03-10 04:39:02
【问题描述】:
我有这个数据框
library(tidyverse)
df <- structure(list(D1_step1 = c("FT", "FF", "FF", "TTT", "FFF", "FFF",
"FF", "FFF", "FT", "TT"), barrido = c("B1_B4", "B1_B2", "B1_B4",
"B1_B2_B4", "B1_B2_B4", "B1_B2_B4", "B1_B4", "B1_B2_B4", "B1_B4",
"B1_B4")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-10L))
和这个函数
f1 <- function(sero, barrido){
as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}
df %>%
mutate(new_col = f1(D1_step1, barrido))
我这样做并且效果很好。我不需要函数中的 barrido 参数,因为它没有变化,并且数据总是有一个名为“barrido”的列。因此,我想这样做....
f2 <- function(sero){
as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}
df %>%
mutate(new_col = f2(D1_step1))
Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) :
object 'barrido' not found
但是计算机说不,所以我尝试将参数设置为默认值,但我得到了另一种不。 Nb 刚刚编辑了这个,因为我最初并没有将参数设置为默认值
f3 <- function(sero, barrido = barrido){
as.logical(case_when(str_detect(barrido, "B1") ~ str_sub(sero, 1, 1)))
}
df %>%
mutate(new_col = f3(D1_step1))
Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) :
promise already under evaluation: recursive default argument reference or earlier problems?
Writing a custom case_when function to use in dplyr mutate using tidyeval。这个问题没有帮助,因为我不想在变异中将函数编写为 case_when 。下面的 cmets 说明了为什么这不起作用,并让我相信可能有使用 tidyeval 的解决方案。我也很好奇 f2 和 f3 之间的错误消息之间的差异背后的原因。
【问题讨论】:
-
函数是独立的,它们不会“附加”到您的数据框。所以你也可以使用
f1(1:10, 11:20)没有任何错误。 (我知道这没有意义,只是为了演示)。同样sero和barrido只是变量,你可以用f1中的a和b替换它们,它仍然可以工作。因此,当您在函数中使用barrido时,它的定义应该出现在函数本身(或全局环境中)的某个位置。 -
所以您希望函数始终在调用它的数据框中使用
barrido的值?有办法做到这一点,例如您可以编写函数以接受数据帧作为输入而不是单个向量,但我不确定它是否比仅传递barrido的值更简洁。 -
@RonakShah。但是当我调用函数时,我使用的是使用 NSE 的 dplyr::mutate,所以我认为数据帧及其变量(包括“barrido”)在函数调用的环境中可用。也许我错了。
-
@Marius 是的。我不希望函数接受数据框(即在其周围包裹一个 mutate),因为它使命名新变量变得困难
-
不,正如我所说的功能是独立的。他们不知道从哪里调用他们。例如
sum函数。它适用于sum(mtcars$mpg)和sum(1:10)。你定义的函数都是一样的。
标签: r function dplyr case-when tidyeval