【发布时间】:2019-12-23 00:11:48
【问题描述】:
考虑以下示例:
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)): no non-missing arguments to 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 package (v0.3.0) 于 2019 年 12 月 22 日创建
让我感到困惑的是(我相信)我构造了TRUE 部分,而FALSE 部分(index[min(which(value))])必须包含一个值。为什么这会发出警告?
这是有问题的,因为我有几千组的数据,其中大多数都在“FALSE”位中,并且警告使计算变得非常缓慢。
我很高兴使用base::ifelse,但我只是想知道dplyr::if_else 是如何评估真假两面的,这是同时进行的吗?
【问题讨论】: