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?
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