使用接受向量、静态值和NULL
s 的参数对 R 函数进行向量化的最佳方法是什么?当我Map()
的函数带有有时带有NULL
s 的参数时,我遇到了问题。我收到以下错误消息(使用下面的代码复制):
Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) : zero-length inputs cannot be mixed with those of non-zero length
为了重现这个问题,我编写了一个函数,该函数n
使用来自data
可选实现的min
和max
值的参数返回模拟值。
#' foo (example function with some args defaulting to NULL)
#'
#' Returns simulated normal values using population parameters from data
#'
#' @param data Numeric vector used to calculate population parameters
#' @param n Number of simulated data points to return
#' @param min Optional. Creates a truncation effect. Simulated values
#' below min will be replaced with min.
#' @param max Optional. Creates a truncation effect. Simulated values
#' above max will be replaced with max.
#' @return Numeric vector of simulated values.
foo <- function(data, n, min = NULL, max = NULL) {
x <- rnorm(n, mean(data), sd(data))
if (!is.null(min)) {
x[x < min] <- min
}
if (!is.null(max)) {
x[x > max] <- max
}
x
}
我正在处理列表并希望该函数返回列表。所以,在这里,数据向量是一个数字向量列表。
## data vector
data <- replicate(5, rnorm(3), simplify = FALSE)
其他参数可以接受静态 ( length(x) == 1
) 或动态值 ( length(x) == length(data)
)。当提供非 NULL 值时,无论给 args 一个还是多个值,它都有效。
## static args (this works)
n <- 10
min <- -1.96
max <- 1.96
Map(foo, data, n, min, max)
## vector args (this works)
n <- sample(2:100, 5)
min <- runif(5, -4, -1)
max <- runif(5, 1, 4)
Map(foo, data, n, min, max)
但是当 args 被传递一个NULL
值时,它会中断。
## null args (this doesn't work)
n <- sample(2:100, 5)
min <- NULL
max <- NULL
Map(foo, data, n, min, max)
## it doesn't matter if n is a vector
n <- 10
min <- NULL
max <- NULL
Map(foo, data, n, min, max)
Error in mapply(FUN = f, ..., SIMPLIFY = FALSE) :
zero-length inputs cannot be mixed with those of non-zero length
我认为你正在寻找的代码是
n <- sample(2:100, 5)
min <- list(NULL)
max <- list(NULL)
Map(foo, data, n, min, max)
该Map
函数期望函数后面的每个参数都是一个向量或参数列表,它们将被回收到最长的长度。因此,在这种情况下,我们有length(data)
和length(n)
等于5和length(min)
和length(max)
等于1,所以在最低和最高列出了单个NULL再循环5次,每次传递给函数。
或者,如果您想做一个类似“应用”的操作,其中一些参数是向量而其他参数是标量(即要传递给函数的每次调用的单个值),请使用mapply
,直接传递向量参数和内部的标量参数MoreArgs
:
n <- sample(2:100, 5)
min <- NULL
max <- NULL
mapply(foo, data, n, MoreArgs=list(min, max))
(此外,为了与您的代码保持一致,我还没有这样做,但是您几乎总是应该将参数传递给具有名称的应用类型函数(例如MoreArgs=list(min=min, max=max)
.)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句