首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dplyr::if_else与purrr

使用dplyr::if_else与purrr
EN

Stack Overflow用户
提问于 2019-06-20 17:17:26
回答 2查看 648关注 0票数 2

如果列表元素是purrr::map_dbl,那么我试图在列表中使用NULL

代码语言:javascript
复制
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)。为什么这个不行?

以下是我所期望的工作:

代码语言:javascript
复制
> 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

最初的电话有什么不同?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-20 17:19:15

我们可以使用browser()轻松地进行调试。

代码语言:javascript
复制
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,它仍然有效。

代码语言:javascript
复制
v1 <- 1
if_else(v1==1, 0, v1[1] + v1[2])
#[1] 0

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

@CBraun做了一个有趣的观察

代码语言:javascript
复制
NULL[1] + NULL[2]
#integer(0)

返回长度0,

代码语言:javascript
复制
if_else(is.na(v1), 0, integer(0))

错误:false必须长度为1(condition的长度),而不是0调用rlang::last_error()才能看到回溯

然而,

NA + NA #1 NA

length 1,但仍返回错误。

代码语言:javascript
复制
v1 <- NA
if_else(is.na(v1), 0, v1[1] + v1[2])

错误:false必须是双向量,而不是整数向量调用rlang::last_error()才能看到回溯

如果我们使用正确的NA分派,它可以工作。

代码语言:javascript
复制
v1 <- NA_real_
if_else(is.na(v1), 0, v1[1] + v1[2])
#[1] 0

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

底线:当值为NULL时,行为很奇怪,因为+的输出是长度为0的integer(0)

在这种情况下,我们可以使用if/else而不是if_else

代码语言:javascript
复制
purrr::map_dbl(x, ~ if(is.null(.x)) 0 else sum(.x))
#[1] 0 3 7 

在这方面,使用sum代替单独调用参数y[[1]]y[[2]],因为这会导致长度不平衡。

代码语言:javascript
复制
purrr::map_dbl(x, ~ ifelse(is.null(.x), 0, sum(.x)))
#[1] 0 3 7

请注意,ifelse还要求长度相同,不过由于值的回收,它在这里工作。

作为测试和数据值的相同长度和属性(包括维度和“类”)的向量,值为yes或no。

代码语言:javascript
复制
purrr::map_dbl(x, ~ ifelse(is.null(.x), 0, .x[[1]] + .x[[2]]))
#[1] 0 3 7

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

票数 3
EN

Stack Overflow用户

发布于 2019-06-20 17:26:48

另一种方法是使用sum中的sum参数来在将值相加时忽略NANULL值。这样,我们就可以跳过if逻辑:

代码语言:javascript
复制
purrr::map_dbl(x, sum, na.rm = TRUE) 
# [1] 0 3 7

以下是基本R当量(正如akrun所指出的):

代码语言:javascript
复制
sapply(x, sum, na.rm = TRUE)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56690964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档