gpt4 book ai didi

r - 将 dplyr::if_else 与 purrr 一起使用

转载 作者:行者123 更新时间:2023-12-02 19:57:38 24 4
gpt4 key购买 nike

我尝试在列表上使用 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]) })

这没有按预期工作,而是给出错误:

Error: false must be length 1 (length of condition), not 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

与原始调用有何不同?

最佳答案

我们可以使用 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 ,要求所有参数具有相同的长度

Values to use for TRUE and FALSE values of condition. They must be either the same length as condition, or length 1. They must also be the same type: if_else() checks that they have the same type and same class. All other attributes are taken from true.


为了进一步深入研究这个问题,如果值不是NULL,它仍然有效。

v1 <- 1
if_else(v1==1, 0, v1[1] + v1[2])
#[1] 0

但是,一旦我们将其更改为 NANULL ,这成为一个问题,可能是由于 type

@CBraun 做了一个有趣的观察

NULL[1] + NULL[2]
#integer(0)

返回长度0,

if_else(is.na(v1), 0, integer(0))

Error: false must be length 1 (length of condition), not 0 Call rlang::last_error() to see a backtrace

但是,

不适用+不适用 #[1] 不适用

length 1,但仍然返回错误

v1 <- NA
if_else(is.na(v1), 0, v1[1] + v1[2])

Error: false must be a double vector, not an integer vector Call rlang::last_error() to see a backtrace

如果我们使用正确的NA已发送,有效

v1 <- NA_real_
if_else(is.na(v1), 0, v1[1] + v1[2])
#[1] 0

请注意,这里是 type问题。总而言之,正如文档中提到的,lengthtype应匹配 if_else

底线:当值为 NULL 时,由于 + 的输出,行为很奇怪是 integer(0)长度为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还要求长度相同,尽管由于值的回收,它在这里起作用

A vector of the same length and attributes (including dimensions and "class") as test and data values from the values of yes or no.

purrr::map_dbl(x, ~ ifelse(is.null(.x), 0, .x[[1]] + .x[[2]]))
#[1] 0 3 7

注意:所有方法均用于检查 OP 的状况。但是,如果目标是获得结果,还有其他方法。

关于r - 将 dplyr::if_else 与 purrr 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56690964/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com