如果列表元素是purrr::map_dbl,那么我试图在列表中使用NULL。
x <- list(NULL, c(1, 2), c(3, 4))
purrr::map_dbl(x, function(y) { dplyr::if_else(is.null(y), 0, y[1] + y[2]) })这不像预期的那样工作,而是提供了错误:
错误:
false必须是长度1(condition的长度),而不是0
调试if_else调用时,我看到y[1] + y[2]被计算为integer(0)。为什么这个不行?
以下是我所期望的工作:
> purrr::map_dbl(x, function(y) { dplyr::if_else(is.null(y), 0, y[1]) })
[1] 0 1 3
> purrr::map_dbl(x, function(y) { dplyr::if_else(is.null(y), 0, y[2]) })
[1] 0 2 4
> purrr::map_dbl(x, ~ dplyr::if_else(is.null(.x), 0, .x[1]))
[1] 0 1 3
> purrr::map_dbl(x, function(y) { base::ifelse(is.null(y), 0, y[1] + y[2]) })
[1] 0 3 7
> purrr::map_dbl(x, function(y) { if (is.null(y)) 0 else y[1] + y[2] })
[1] 0 3 7最初的电话有什么不同?
发布于 2019-06-20 17:19:15
我们可以使用browser()轻松地进行调试。
purrr::map_dbl(x, function(y) {
browser()
dplyr::if_else(is.null(y), 0, y[1] + y[2])
})
Called from: .f(.x[[i]], ...)
Browse[1]>
debug at #1: dplyr::if_else(is.null(y), 0, y[1] + y[2])
Browse[2]>
Error: `false` must be length 1 (length of `condition`), not 0
Call `rlang::last_error()` to see a backtrace因此,length就是问题所在。
根据?if_else,要求所有参数都具有相同的长度
用于条件的真值和假值的值。它们必须是与条件相同的长度,或者是长度1。它们也必须是相同的类型: if_else()检查它们是否具有相同的类型和类。所有其他属性都取自true。
为了更深入地研究这个问题,如果值不是NULL,它仍然有效。
v1 <- 1
if_else(v1==1, 0, v1[1] + v1[2])
#[1] 0但是,一旦我们将它更改为NA或NULL,它就会成为一个问题,可能是由于type
@CBraun做了一个有趣的观察
NULL[1] + NULL[2]
#integer(0)返回长度0,
if_else(is.na(v1), 0, integer(0))错误:
false必须长度为1(condition的长度),而不是0调用rlang::last_error()才能看到回溯
然而,
NA + NA #1 NA
为length 1,但仍返回错误。
v1 <- NA
if_else(is.na(v1), 0, v1[1] + v1[2])错误:
false必须是双向量,而不是整数向量调用rlang::last_error()才能看到回溯
如果我们使用正确的NA分派,它可以工作。
v1 <- NA_real_
if_else(is.na(v1), 0, v1[1] + v1[2])
#[1] 0请注意,这里是type问题。总之,正如文档中提到的,length和type应该与if_else匹配。
底线:当值为NULL时,行为很奇怪,因为+的输出是长度为0的integer(0)。
在这种情况下,我们可以使用if/else而不是if_else
purrr::map_dbl(x, ~ if(is.null(.x)) 0 else sum(.x))
#[1] 0 3 7 在这方面,使用sum代替单独调用参数y[[1]]、y[[2]],因为这会导致长度不平衡。
purrr::map_dbl(x, ~ ifelse(is.null(.x), 0, sum(.x)))
#[1] 0 3 7请注意,ifelse还要求长度相同,不过由于值的回收,它在这里工作。
作为测试和数据值的相同长度和属性(包括维度和“类”)的向量,值为yes或no。
purrr::map_dbl(x, ~ ifelse(is.null(.x), 0, .x[[1]] + .x[[2]]))
#[1] 0 3 7注意:所有的方法都是用来检查OP的情况。但是,如果目标是获得结果,还有其他方法。
发布于 2019-06-20 17:26:48
另一种方法是使用sum中的sum参数来在将值相加时忽略NA或NULL值。这样,我们就可以跳过if逻辑:
purrr::map_dbl(x, sum, na.rm = TRUE)
# [1] 0 3 7以下是基本R当量(正如akrun所指出的):
sapply(x, sum, na.rm = TRUE)https://stackoverflow.com/questions/56690964
复制相似问题