is_quosure(x) 转发时出错...在地图内
is_quosure(x) error when forwarding ... inside map
我想为内部函数定义一个包装器。
这个想法是重复使用 r*
基本函数之一(例如 runif
、rnorm
等)的随机抽样,让用户轻松更改此内部函数并定义自定义函数。
下面的示例显示了一个可重现的示例,我无法使用 tidyeval
模式,更准确地说,在 purrr::map
中。 ...
的评估似乎没有正确发生。我错过了关于 quosures 评估的一些东西,但我不知道是什么。我还在下面展示了一个解决方法,它适用于旧的 replicate
.
我想在更复杂的情况下实现这样的行为,并且更普遍地,对任何指针都感到高兴,并理解为什么以下内容不起作用。
# use the tidyverse and define a dummy tibble
library(tidyverse)
df <- tibble(col1=seq(10, 50, 10), col2=col1+5)
# first random function, on top of stats::runif
random_1 <- function(x, min, max){
x %>%
rowwise() %>%
mutate(new=runif(1, min={{min}}, max={{max}})) %>%
ungroup()
}
# second random function, on top of stats::rnorm
random_2 <- function(x, mean, sd){
x %>%
rowwise() %>%
mutate(new=rnorm(1, mean={{mean}}, sd={{sd}})) %>%
ungroup()
}
# at top level, everything works fine
> df %>% random_1(min=col1, max=col2)
> df %>% random_2(mean=col1, sd=col2)
# So far so good
# we we wrap it for a single shot
random_fun <- function(x, random_fun, ...){
random_fun(x, ...)
}
random_fun(df, random_1, min=col1, max=col2)
# Still fine.
# Here comes the trouble:
random_fun_k <- function(df, k, random_fun, ...){
map(1:k, ~random_fun(df, ...))
}
random_fun_k(df, k=2, random_1, min=col1, max=col2)
Error in is_quosure(x) : argument "x" is missing, with no default
围绕 replicate
的以下解决方法工作正常,但我想坚持 tidyeval 精神:
random_fun_k_oldie <- function(df, k, random_fun, ...){
f <- random_fun(df, ...)
replicate(k, f, simplify=FALSE)
}
random_fun_k_oldie(df, k=2, random_1, min=col1, max=col2)
random_fun_k_oldie(df, k=2, random_2, mean=col1, sd=col2)
最好使用原始的 lambda 函数,即 function(x)
library(purrr)
random_fun_k <- function(df, k, random_fun, ...){
map(seq_len(k), function(x) random_fun(df, ...))
}
-测试
> random_fun_k(df, k=2, random_1, min=col1, max=col2)
[[1]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 12.6
2 20 25 21.4
3 30 35 34.1
4 40 45 40.7
5 50 55 53.8
[[2]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 13.1
2 20 25 24.2
3 30 35 33.8
4 40 45 41.6
5 50 55 50.9
注意:函数名称和参数名称似乎相同 rand_fun
,这也可能导致一些混淆(尽管这不是错误的来源)。以不同的方式重命名函数参数可能会更好
random_fun <- function(x, rn_fun, ...){
rn_fun(x, ...)
}
purrr 的 lambda 支持使用 ..1
、..2
等语法的位置参数。这是通过 ...
机制实现的。因此,您没有将正确的参数传递给 random_fun
.
解决方案是按照 akrun 的建议使用普通的 lambda 函数。也许你可以使用 R 4.0 的 \(x) x
语法。
我想为内部函数定义一个包装器。
这个想法是重复使用 r*
基本函数之一(例如 runif
、rnorm
等)的随机抽样,让用户轻松更改此内部函数并定义自定义函数。
下面的示例显示了一个可重现的示例,我无法使用 tidyeval
模式,更准确地说,在 purrr::map
中。 ...
的评估似乎没有正确发生。我错过了关于 quosures 评估的一些东西,但我不知道是什么。我还在下面展示了一个解决方法,它适用于旧的 replicate
.
我想在更复杂的情况下实现这样的行为,并且更普遍地,对任何指针都感到高兴,并理解为什么以下内容不起作用。
# use the tidyverse and define a dummy tibble
library(tidyverse)
df <- tibble(col1=seq(10, 50, 10), col2=col1+5)
# first random function, on top of stats::runif
random_1 <- function(x, min, max){
x %>%
rowwise() %>%
mutate(new=runif(1, min={{min}}, max={{max}})) %>%
ungroup()
}
# second random function, on top of stats::rnorm
random_2 <- function(x, mean, sd){
x %>%
rowwise() %>%
mutate(new=rnorm(1, mean={{mean}}, sd={{sd}})) %>%
ungroup()
}
# at top level, everything works fine
> df %>% random_1(min=col1, max=col2)
> df %>% random_2(mean=col1, sd=col2)
# So far so good
# we we wrap it for a single shot
random_fun <- function(x, random_fun, ...){
random_fun(x, ...)
}
random_fun(df, random_1, min=col1, max=col2)
# Still fine.
# Here comes the trouble:
random_fun_k <- function(df, k, random_fun, ...){
map(1:k, ~random_fun(df, ...))
}
random_fun_k(df, k=2, random_1, min=col1, max=col2)
Error in is_quosure(x) : argument "x" is missing, with no default
围绕 replicate
的以下解决方法工作正常,但我想坚持 tidyeval 精神:
random_fun_k_oldie <- function(df, k, random_fun, ...){
f <- random_fun(df, ...)
replicate(k, f, simplify=FALSE)
}
random_fun_k_oldie(df, k=2, random_1, min=col1, max=col2)
random_fun_k_oldie(df, k=2, random_2, mean=col1, sd=col2)
最好使用原始的 lambda 函数,即 function(x)
library(purrr)
random_fun_k <- function(df, k, random_fun, ...){
map(seq_len(k), function(x) random_fun(df, ...))
}
-测试
> random_fun_k(df, k=2, random_1, min=col1, max=col2)
[[1]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 12.6
2 20 25 21.4
3 30 35 34.1
4 40 45 40.7
5 50 55 53.8
[[2]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 13.1
2 20 25 24.2
3 30 35 33.8
4 40 45 41.6
5 50 55 50.9
注意:函数名称和参数名称似乎相同 rand_fun
,这也可能导致一些混淆(尽管这不是错误的来源)。以不同的方式重命名函数参数可能会更好
random_fun <- function(x, rn_fun, ...){
rn_fun(x, ...)
}
purrr 的 lambda 支持使用 ..1
、..2
等语法的位置参数。这是通过 ...
机制实现的。因此,您没有将正确的参数传递给 random_fun
.
解决方案是按照 akrun 的建议使用普通的 lambda 函数。也许你可以使用 R 4.0 的 \(x) x
语法。