dplyr return current value of row

Viewed 24

Data sample

library(tidyverse)
df <- tibble(range = c("2022-01-01", "2022-01-01", "2022-02-01", "2022-02-01"),
             gender = c("F", "M", "F", "M"),
             value = c(15, 8, 7, 0))

What I want to do is check if for any month (range) there exists a zero value, make both rows 0. If that isn't the case, keep the current values. I thought I would be able to do that by

df_table <- df %>% 
  group_by(range) %>% 
  mutate(value = if_else(any(value == 0), 0, value))

However I run into the error that false must be length 1 (length of `condition`), not 2. Any idea how I can get it to give back the current value for the row?

Expected output

> df
# A tibble: 4 x 3
  range      gender value
  <chr>      <chr>  <dbl>
1 2022-01-01 F         15
2 2022-01-01 M          8
3 2022-02-01 F          0
4 2022-02-01 M          0

Thank you!

1 Answers

We could use if/else instead of ifelse as the lengths of each argument should be equal for ifelse - any returns TRUE/FALSE of length 1, the 'yes' argument 0 is of length 1 where as 'no' for value is length equal to group size

library(dplyr)
df %>% 
  group_by(range) %>%
   mutate(value = if(any(value == 0)) 0 else value) %>%
   ungroup

-output

# A tibble: 4 × 3
  range      gender value
  <chr>      <chr>  <dbl>
1 2022-01-01 F         15
2 2022-01-01 M          8
3 2022-02-01 F          0
4 2022-02-01 M          0

Or without any if/else condition by multiplying the numeric column with the logical vector (FALSE -> 0 and TRUE -> 1)

df %>% 
  group_by(range) %>% 
  mutate(value = value * !any(value == 0)) %>%
  ungroup
# A tibble: 4 × 3
  range      gender value
  <chr>      <chr>  <dbl>
1 2022-01-01 F         15
2 2022-01-01 M          8
3 2022-02-01 F          0
4 2022-02-01 M          0
Related