0

I have a dataframe jj:

jj<-data.frame(a=rep(1:3,3),b=c(TRUE,rep(FALSE,4),TRUE,TRUE,FALSE,TRUE))

I want to create a third column that will be true if any of the rows with a particular a have b==TRUE. So I tried this:

group_by(jj,a) %>% mutate(c=any(isTRUE(b)))

But the result I got is this:

# A tibble: 9 x 3
# Groups:   a [3]
      a b     c    
  <int> <lgl> <lgl>
1     1 TRUE  FALSE
2     2 FALSE FALSE
3     3 FALSE FALSE
4     1 FALSE FALSE
5     2 FALSE FALSE
6     3 TRUE  FALSE
7     1 TRUE  FALSE
8     2 FALSE FALSE
9     3 TRUE  FALSE

My expected result should have been this:

# A tibble: 9 x 3
# Groups:   a [3]
      a b     c    
  <int> <lgl> <lgl>
1     1 TRUE  TRUE
2     2 FALSE FALSE
3     3 FALSE TRUE
4     1 FALSE TRUE
5     2 FALSE FALSE
6     3 TRUE  TRUE
7     1 TRUE  TRUE
8     2 FALSE FALSE
9     3 TRUE  TRUE

I don't even understand why I get all FALSE -- it would've made sense if it was all TRUE, and I would think that any() is getting the full column for some reason. What am I missing, and how can I achieve the desired result?

iod
  • 6,861
  • 2
  • 13
  • 30

1 Answers1

3

We need to apply any on the logical column and not isTRUE

jj %>% 
  group_by(a) %>%
  mutate(c = any(b))
# A tibble: 9 x 3
# Groups:   a [3]
#      a b     c    
#  <int> <lgl> <lgl>
#1     1 TRUE  TRUE 
#2     2 FALSE FALSE
#3     3 FALSE TRUE 
#4     1 FALSE TRUE 
#5     2 FALSE FALSE
#6     3 TRUE  TRUE 
#7     1 TRUE  TRUE 
#8     2 FALSE FALSE
#9     3 TRUE  TRUE 

The reason is that isTRUE is otherwise (from the ?isTRUE)

is.logical(x) && length(x) == 1 && !is.na(x) && x 

the rhs expression of && will be be evaluated only if the expression lhs are all true

here, the length(x) equals to 1 is not correct, so it returns FALSE

akrun
  • 674,427
  • 24
  • 381
  • 486