传递要在 Reduce 中的函数调用中评估的省略号参数
Passing elipsis argument to be evaluated within function call within Reduce
背景
我有一个有趣的函数,可以使用 all.equal
比较列表中的向量。当我使用 all.equal
时,我想通过省略号传递相关的 all.equal
参数。无需向 all.equal
传递任何内容,该函数就可以正常工作。
功能目标
- 该函数旨在提供
all.equal
调用的修改版本,可处理任意数量的向量
- 每个向量可以有任意数量的元素;但是,如果所有向量的长度都不相等,则该函数将 return false。
- 该函数应该能够利用
all.equal
中可用的参数。例如,如果提供具有正确值的 tolerance
参数,向量 c(1.1, 2)
、c(1, 2)
和 c(1.3, 2)
将被视为相等。 这个问题是关于如何让它工作的。
例子
比较 1,000 个向量,每个向量由三个整数组成。
compare_multiple_vectors(x = lapply(
X = vector(mode = "list", length = 1e3),
FUN = function(...) {
c(1, 2, 3)
}
))
# [1] TRUE
问题/期望的结果
all.equal
在以下向量列表中使用 tolerance = 1
调用将 return 预期 TRUE
all.equal(c(1,2), c(1,1), tolerance = 1)
# [1] TRUE
tolerance = 1
参数无法过滤到 Reduce
内部。
compare_multiple_vectors(x = list(c(1,2), c(1,1)), tolerance = 1)
# [1] FALSE
想要的结果应该是TRUE
.
代码
#' @title Compare Values of Multiple Vectors
#'
#' @description The function compares values across multiple vectors using
#' \code{\link[base]{all.equal}}.
#'
#' @param x Alist of vectors to compare
#' @param ... as in \code{\link[base]{all.equal}}
#'
#' @return A logical
#'
#' @export
#'
#' @importFrom checkmate assert_atomic_vector
#'
#' @examples
#' # Returns TRUE
#' compare_multiple_vectors(c(1,1,1), c(1,1,1))
#' # Returns FALSE
#' compare_multiple_vectors(c(1,1,1), c(1,1,1), c(1,2,1))
#' # Returns FALSE
#' compare_multiple_vectors(c(1,2,3), c(3,2,1))
compare_multiple_vectors <- function(x, ...) {
# Check if all elements of x are atomic vectors
Vectorize(FUN = checkmate::assert_atomic_vector,
vectorize.args = "x")(x)
# Compare list elements
Reduce(
f = function(a, b, ...) {
if (isTRUE(all.equal(target = a, current = b, ...))) {
a
} else {
FALSE
}
},
x = x
) -> res_red
# Return results
if (isFALSE(res_red)) {
return(FALSE)
} else {
return(TRUE)
}
}
备注
我有兴趣使用省略号并让初始调用保持原样
compare_multiple_vectors(x = list_of_vectors_to_compare,
... # all.equal arguments
)
我认为只需要一点点改变:
compare_multiple_vectors <- function(x, ...) {
# Check if all elements of x are atomic vectors
Vectorize(FUN = checkmate::assert_atomic_vector,
vectorize.args = "x")(x)
# Compare list elements
Reduce(
f = function(a, b) { # <===================== Remove *...*
if (isTRUE(all.equal(target = a, current = b, ...))) {
a
} else {
FALSE
}
},
x = x
) -> res_red
# Return results
if (isFALSE(res_red)) {
return(FALSE)
} else {
return(TRUE)
}
}
Reduce 的参数 f 似乎有一个 signature 像 函数(x,y)。所以 Reduce 将忽略 ... 在 f 中。如果删除 f 的省略号,... 将从外部 space 引用,并将得到您想要的正确结果。
背景
我有一个有趣的函数,可以使用 all.equal
比较列表中的向量。当我使用 all.equal
时,我想通过省略号传递相关的 all.equal
参数。无需向 all.equal
传递任何内容,该函数就可以正常工作。
功能目标
- 该函数旨在提供
all.equal
调用的修改版本,可处理任意数量的向量 - 每个向量可以有任意数量的元素;但是,如果所有向量的长度都不相等,则该函数将 return false。
- 该函数应该能够利用
all.equal
中可用的参数。例如,如果提供具有正确值的tolerance
参数,向量c(1.1, 2)
、c(1, 2)
和c(1.3, 2)
将被视为相等。 这个问题是关于如何让它工作的。
例子
比较 1,000 个向量,每个向量由三个整数组成。
compare_multiple_vectors(x = lapply(
X = vector(mode = "list", length = 1e3),
FUN = function(...) {
c(1, 2, 3)
}
))
# [1] TRUE
问题/期望的结果
all.equal
在以下向量列表中使用 tolerance = 1
调用将 return 预期 TRUE
all.equal(c(1,2), c(1,1), tolerance = 1)
# [1] TRUE
tolerance = 1
参数无法过滤到 Reduce
内部。
compare_multiple_vectors(x = list(c(1,2), c(1,1)), tolerance = 1)
# [1] FALSE
想要的结果应该是TRUE
.
代码
#' @title Compare Values of Multiple Vectors
#'
#' @description The function compares values across multiple vectors using
#' \code{\link[base]{all.equal}}.
#'
#' @param x Alist of vectors to compare
#' @param ... as in \code{\link[base]{all.equal}}
#'
#' @return A logical
#'
#' @export
#'
#' @importFrom checkmate assert_atomic_vector
#'
#' @examples
#' # Returns TRUE
#' compare_multiple_vectors(c(1,1,1), c(1,1,1))
#' # Returns FALSE
#' compare_multiple_vectors(c(1,1,1), c(1,1,1), c(1,2,1))
#' # Returns FALSE
#' compare_multiple_vectors(c(1,2,3), c(3,2,1))
compare_multiple_vectors <- function(x, ...) {
# Check if all elements of x are atomic vectors
Vectorize(FUN = checkmate::assert_atomic_vector,
vectorize.args = "x")(x)
# Compare list elements
Reduce(
f = function(a, b, ...) {
if (isTRUE(all.equal(target = a, current = b, ...))) {
a
} else {
FALSE
}
},
x = x
) -> res_red
# Return results
if (isFALSE(res_red)) {
return(FALSE)
} else {
return(TRUE)
}
}
备注
我有兴趣使用省略号并让初始调用保持原样
compare_multiple_vectors(x = list_of_vectors_to_compare, ... # all.equal arguments )
我认为只需要一点点改变:
compare_multiple_vectors <- function(x, ...) {
# Check if all elements of x are atomic vectors
Vectorize(FUN = checkmate::assert_atomic_vector,
vectorize.args = "x")(x)
# Compare list elements
Reduce(
f = function(a, b) { # <===================== Remove *...*
if (isTRUE(all.equal(target = a, current = b, ...))) {
a
} else {
FALSE
}
},
x = x
) -> res_red
# Return results
if (isFALSE(res_red)) {
return(FALSE)
} else {
return(TRUE)
}
}
Reduce 的参数 f 似乎有一个 signature 像 函数(x,y)。所以 Reduce 将忽略 ... 在 f 中。如果删除 f 的省略号,... 将从外部 space 引用,并将得到您想要的正确结果。