1

Actually while attempting this problem I came across a weird situation where baseR's if() else() is working as expected but neither of ifelse and if_else are working. Let me rephrase the actual problem here.

The values in a vector are to be accumulated over set operation union until unique count reaches >3 and in that case it resets. So for a df say y with a single column a, the expected outcome is-

y <- data.frame(a=c(1, 2, 2, 3, 3, 4, 3, 2, 2, 5, 6, 7, 9, 8))

y
   a       b
1  1       1
2  2    1, 2
3  2    1, 2
4  3 1, 2, 3
5  3 1, 2, 3
6  4       4
7  3    4, 3
8  2 4, 3, 2
9  2 4, 3, 2
10 5       5
11 6    5, 6
12 7 5, 6, 7
13 9       9
14 8    9, 8

Now the problem is, that base R 's if() else () is working inside purrr::accumulate whereas neither if_else nor ifelse is working! Can anyone elaborate the reasons?

y <- data.frame(a=c(1, 2, 2, 3, 3, 4, 3, 2, 2, 5, 6, 7, 9, 8))
y
#>    a
#> 1  1
#> 2  2
#> 3  2
#> 4  3
#> 5  3
#> 6  4
#> 7  3
#> 8  2
#> 9  2
#> 10 5
#> 11 6
#> 12 7
#> 13 9
#> 14 8
library(tidyverse)

#this works
accumulate(y$a, ~if(length(union(.x, .y)) == 4) .y else union(.x, .y))
#> [[1]]
#> [1] 1
#> 
#> [[2]]
#> [1] 1 2
#> 
#> [[3]]
#> [1] 1 2
#> 
#> [[4]]
#> [1] 1 2 3
#> 
#> [[5]]
#> [1] 1 2 3
#> 
#> [[6]]
#> [1] 4
#> 
#> [[7]]
#> [1] 4 3
#> 
#> [[8]]
#> [1] 4 3 2
#> 
#> [[9]]
#> [1] 4 3 2
#> 
#> [[10]]
#> [1] 5
#> 
#> [[11]]
#> [1] 5 6
#> 
#> [[12]]
#> [1] 5 6 7
#> 
#> [[13]]
#> [1] 9
#> 
#> [[14]]
#> [1] 9 8
# While these didn't
accumulate(y$a, ~ifelse(length(union(.x, .y)) == 4, .y, union(.x, .y)))
#>  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1
accumulate(y$a, ~if_else(length(union(.x, .y)) == 4, .y, union(.x, .y)))
#> Error: `false` must be length 1 (length of `condition`), not 2.

Created on 2021-05-14 by the reprex package (v2.0.0)

AnilGoyal
  • 25,297
  • 4
  • 27
  • 45
  • 3
    I'm sure this is a dup, but I couldn't find the original. The reason is that `ifelse` is not the same as `if ... else`. The result of `ifelse` is always the same length as the test value, i.e. 1 when the test is `length(union(.x, .y)) == 4`. – user2554330 May 14 '21 at 11:53

0 Answers0