I'm trying to create a binary T/F column, which is T if a 1 is present in that particular row of the dataframe.
df <- tibble(
d1 = c(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
d2 = c(0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0),
d3 = c(0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
d4 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
d5 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
d6 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
d7 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0),
d8 = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0)
)
I can use the following approach to achieve what I want:
df$d9 <- NA
df$d9[df$d1 == 1] <- TRUE
df$d9[df$d2 == 1] <- TRUE
df$d9[df$d3 == 1] <- TRUE
df$d9[df$d4 == 1] <- TRUE
df$d9[df$d5 == 1] <- TRUE
df$d9[df$d6 == 1] <- TRUE
df$d9[df$d7 == 1] <- TRUE
df$d9[df$d8 == 1] <- TRUE
Which results in:
d1 d2 d3 d4 d5 d6 d7 d8 d9
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <lgl>
1 1 0 0 0 0 0 0 0 TRUE
2 0 0 0 0 0 0 0 0 NA
3 0 0 1 0 0 0 0 0 TRUE
4 0 0 0 0 0 0 0 0 NA
5 0 0 0 0 0 0 0 0 NA
6 0 0 0 0 0 0 0 0 NA
7 0 0 0 0 0 0 0 1 TRUE
8 0 1 0 0 0 0 0 0 TRUE
9 0 0 0 0 0 0 0 0 NA
10 0 0 0 0 0 0 0 0 NA
11 0 0 0 1 0 0 1 0 TRUE
12 0 0 0 0 0 0 0 0 NA
13 0 0 0 0 0 0 0 0 NA
14 0 0 0 0 0 0 0 0 NA
15 0 0 0 0 0 0 0 0 NA
But I am sure there must be a more elegant solution to this problem.
First, I would like to be able to create a variable containing the column names that need to be checked i.e. dfCols <- c("d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8") and call this when checking, rather than explicitly calling each of 'd1', 'd2', etc.
I also feel there must be a tidyverse/dplyr solution out there, but have struggled to find one.
UPDATE
Based on the excellent answers provided here, as well as a similar SO entry for a similar question found here, I was able to develop the solution I needed.
First, whilst my reproducible example contained integers, I also wanted to work with character data, as per this tibble:
df <- tibble(
d1 = c('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'),
d2 = c('b', 'a', 'b', 'a', 'a', 'a', 'a', 'a'),
d3 = c('a', 'a', 'a', 'c', 'a', 'b', 'a', 'a'),
d4 = c('a', 'a', 'a', 'a', 'a', 'a', 'a', 'd'),
d5 = c('a', 'c', 'a', 'a', 'a', 'a', 'a', 'a'),
d6 = c('a', 'a', 'a', 'b', 'a', 'a', 'e', 'a'),
d7 = c('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'),
d8 = c('a', 'a', 'a', 'a', 'a', 'a', 'a', 'a')
)
Second, for ease of use, I wanted to be able to specify the cols I wanted to check over:
cols <- c('d2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8')
Finally, I wanted to be able to pass a list of test characters to check if they were in the rows:
bcde <- c('b', 'c', 'd', 'e')
The following code fulfils these criteria:
df <- df %>%
mutate(
d9 = case_when(
if_any(all_of(cols), ~ . %in% bcde) ~ 1,
TRUE ~ 0)
)