Reputation: 1800
I have a data frame like this (with more vars)
tb = data.frame(ID=c("a","b","c"),V1=c(TRUE,FALSE,TRUE),
V2=c(FALSE,FALSE,TRUE),V3=c(TRUE,TRUE,FALSE) )
tb
ID V1 V2 V3
1 a TRUE FALSE TRUE
2 b FALSE FALSE TRUE
3 c TRUE TRUE FALSE
I need to add a fourth variable with the sum of true values by row like this but conserving all the other vars
tb %>%
select(V1:V3) %>%
mutate(out = rowSums(.))
V1 V2 V3 out
1 TRUE FALSE TRUE 2
2 FALSE FALSE TRUE 1
3 TRUE TRUE FALSE 2
Upvotes: 2
Views: 1682
Reputation: 9868
The dplyr solution
In a single call, you can use the selection helper where
inside across
to feed only the columns that meet a condition (is.logical
) to rowSums
.
tb %>% mutate(sum = rowSums(across(where(is.logical))))
ID V1 V2 V3 sum
1 a TRUE FALSE TRUE 2
2 b FALSE FALSE TRUE 1
3 c TRUE TRUE FALSE 2
You can also select the columns by name inside across, or with name patterns with starts_with
or matches
:
tb %>% mutate(sum = rowSums(across(V1:V3)))
#OR
tb %>% mutate(sum = rowSums(across(starts_with("V"))))
#OR
tb %>% mutate(sum = rowSums(across(matches("V\\d"))))
Upvotes: 6
Reputation: 33488
Maybe not the dplyr
way but you could use select()
within mutate()
like so:
tb %>% mutate(out = rowSums(tb %>% select(V1:V3)))
ID V1 V2 V3 out
1 a TRUE FALSE TRUE 2
2 b FALSE FALSE TRUE 1
3 c TRUE TRUE FALSE 2
Upvotes: 2