r - dplyr::if_else 是否同时评估 TRUE 和 FALSE?
问题描述
考虑以下示例:
library(dplyr)
# sample data
set.seed(1)
mydf <- data.frame(value = as.logical(sample(0:1, 15, replace = TRUE)), group = rep(letters[1:3],each = 5), index = 1:5)
# finds either index of first "TRUE" value by group, or the last value.
# works with base::ifelse
mydf %>% group_by(group) %>% mutate(max_value = ifelse(all(!value), max(index), index[min(which(value))]))
#> # A tibble: 15 x 4
#> # Groups: group [3]
#> value group index max_value
#> <lgl> <fct> <int> <int>
#> 1 FALSE a 1 2
#> 2 TRUE a 2 2
#> 3 FALSE a 3 2
#> 4 FALSE a 4 2
#> 5 TRUE a 5 2
#> 6 FALSE b 1 4
#> 7 FALSE b 2 4
#> 8 FALSE b 3 4
#> 9 TRUE b 4 4
#> 10 TRUE b 5 4
#> 11 FALSE c 1 5
#> 12 FALSE c 2 5
#> 13 FALSE c 3 5
#> 14 FALSE c 4 5
#> 15 FALSE c 5 5
# the same gives a warning with dplyr::if_else
mydf %>% group_by(group) %>% mutate(max_value = if_else(all(!value), max(index), index[min(which(value))]))
#> Warning in min(which(value)): no non-missing arguments to min; returning Inf
#> # A tibble: 15 x 4
#> # Groups: group [3]
#> value group index max_value
#> <lgl> <fct> <int> <int>
#> 1 FALSE a 1 2
#> 2 TRUE a 2 2
#> 3 FALSE a 3 2
#> 4 FALSE a 4 2
#> 5 TRUE a 5 2
#> 6 FALSE b 1 4
#> 7 FALSE b 2 4
#> 8 FALSE b 3 4
#> 9 TRUE b 4 4
#> 10 TRUE b 5 4
#> 11 FALSE c 1 5
#> 12 FALSE c 2 5
#> 13 FALSE c 3 5
#> 14 FALSE c 4 5
#> 15 FALSE c 5 5
如代码中所述 -dplyr::if_else
确实会导致警告
min(which(value)) 中的警告:min 没有非缺失参数;返回 Inf
删除“all FALSE”组 c - 不再警告:
mydf_allTRUE <- mydf
mydf_allTRUE[14, 'value'] <- TRUE
mydf_allTRUE %>% group_by(group) %>% mutate(max_value = if_else(all(!value), max(index), index[min(which(value))]))
#> # A tibble: 15 x 4
#> # Groups: group [3]
#> value group index max_value
#> <lgl> <fct> <int> <int>
#> 1 FALSE a 1 2
#> 2 TRUE a 2 2
#> 3 FALSE a 3 2
#> 4 FALSE a 4 2
#> 5 TRUE a 5 2
#> 6 FALSE b 1 4
#> 7 FALSE b 2 4
#> 8 FALSE b 3 4
#> 9 TRUE b 4 4
#> 10 TRUE b 5 4
#> 11 FALSE c 1 4
#> 12 FALSE c 2 4
#> 13 FALSE c 3 4
#> 14 TRUE c 4 4
#> 15 FALSE c 5 4
由reprex 包(v0.3.0)于 2019 年 12 月 22 日创建
让我感到困惑的是(我相信)我以部件 ( )必须包含值TRUE
的方式构造部件。为什么这会发出警告?这是有问题的,因为我有几千组的数据,其中大部分都在“FALSE”位中,并且警告使计算非常慢。FALSE
index[min(which(value))]
我很高兴使用base::ifelse
,但我只是想知道如何dplyr::if_else
评估 TRUE 和 FALSE 方面,这是同时进行的吗?
解决方案
问题是因为我们正在检查有返回NULL with
which(value)`的组的情况
min(NULL)
#[1] Inf
警告消息:在 min(NULL) 中:min 没有非缺失参数;返回 Inf
一个选项是which
通过索引来处理输出[1]
以返回NA
mydf %>%
group_by(group) %>%
mutate(max_value = if_else(all(!value), max(index), index[which(value)[1]]))
# A tibble: 15 x 4
# Groups: group [3]
# value group index max_value
# <lgl> <fct> <int> <int>
# 1 FALSE a 1 2
# 2 TRUE a 2 2
# 3 FALSE a 3 2
# 4 FALSE a 4 2
# 5 TRUE a 5 2
# 6 FALSE b 1 4
# 7 FALSE b 2 4
# 8 FALSE b 3 4
# 9 TRUE b 4 4
#10 TRUE b 5 4
#11 FALSE c 1 5
#12 FALSE c 2 5
#13 FALSE c 3 5
#14 FALSE c 4 5
#15 FALSE c 5 5
此外,在这种情况下,由于我们返回单个元素,if/else
因此会更合适
mydf %>%
group_by(group) %>%
mutate(max_value = if(all(!value)) max(index) else index[which(value)[1]])
# A tibble: 15 x 4
# Groups: group [3]
# value group index max_value
# <lgl> <fct> <int> <int>
# 1 FALSE a 1 2
# 2 TRUE a 2 2
# 3 FALSE a 3 2
# 4 FALSE a 4 2
# 5 TRUE a 5 2
# 6 FALSE b 1 4
# 7 FALSE b 2 4
# 8 FALSE b 3 4
# 9 TRUE b 4 4
#10 TRUE b 5 4
#11 FALSE c 1 5
#12 FALSE c 2 5
#13 FALSE c 3 5
#14 FALSE c 4 5
#15 FALSE c 5 5
推荐阅读
- vb.net - 在交集列表中放置一个条件(计数长度)
- angular - 在 .pipe() 中使用 delay(2000) 时,.subscribe 不会被触发。(角度 Rxjs)
- vue.js - 我可以将默认端口从 8080 更改为 Vue 中的其他端口吗?
- php - Laravel:比较数据库中两列之间的日期不起作用
- redirect - 如何将ip重定向到子域
- spring - 我想获取一个数据库中的所有表并在jsp中显示
- r - lrtest(似然比检验)使用plgm包计数数据
- php - Composer 自动加载性能
- cordova - OneSignal 订阅用户?
- postgresql - 复杂匹配和加入 PostgreSQL