【发布时间】:2019-05-27 04:03:29
【问题描述】:
背景
我有一个有趣的函数,它使用all.equal 比较列表中的向量。当我使用all.equal 时,我想通过省略号传递相关的all.equal 参数。无需向all.equal 传递任何内容,该函数即可按需要工作。
功能目标
- 该函数旨在提供
all.equal调用的修改版本,可处理任意数量的向量 - 每个向量可以有任意数量的元素;但是,如果所有向量的长度不同,则该函数将返回 false。
- 该函数应该能够利用
all.equal中可用的参数。例如,如果提供了具有正确值的tolerance参数,则向量c(1.1, 2)、c(1, 2)和c(1.3, 2)将被视为相等。 问题在于如何让它发挥作用。
示例
比较 1000 个向量,每个向量由三个整数组成。
compare_multiple_vectors(x = lapply(
X = vector(mode = "list", length = 1e3),
FUN = function(...) {
c(1, 2, 3)
}
))
# [1] TRUE
问题/期望的结果
在以下向量列表中使用tolerance = 1 调用all.equal 将返回预期的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 )
【问题讨论】:
-
Reduce没有...参数,但Map有。像Map(function(a, b, ...) all.equal(a, b, ...), list(c(1,2)), list(c(1,1)), tolerance = 1)这样的事情会做吗?请注意,该列表现在是两个列表。 -
或者只是
Map(all.equal, list(c(1,2)), list(c(1,1)), tolerance = 1)。显然,Map识别了all.equal的省略号参数。 -
@RuiBarradas 我认为这可行;这如何影响性能,因为 Reduce 将始终比较两个向量?另外,我想将一个参数作为向量列表传递给检查,对于 Map,这将不得不分解为单独的列表,具有奇数个向量的列表呢?
-
我认为目前尚不清楚您正在尝试哪种比较以及需要哪种错误检查。我们可以假设列表中的所有条目的长度都是 2 吗?还是有些长度不同?这一切都需要一组用于测试的测试用例和一组相应的解释,为什么应该提供指定的结果。并且结果是否不需要以列表的形式而不是向量的形式? (投票结束时不清楚,但会鼓励您澄清,以便我可以推翻我的投票。)
-
@42- 感谢您查看此内容。我已经阐明了该函数应该做什么。
标签: r function functional-programming namespaces ellipsis