I would like to pass a column selection to a dplyr function (across) inside an ifelse statement.
This is my data:
tibble(var1 = c(NA,1,2),
var2 = c(NA,NA,3),
var3 = c(NA,0,0),
do_not_touch = c(1:3)
) -> test
This is what I was trying:
test %>%
mutate( new_col = test %>%
select(starts_with("var")) %>%
ifelse(if_all(., is.na), NA, rowSums(across(.), na.rm=T)) )
This is what I was expecting:
# A tibble: 3 x 5
var1 var2 var3 do_not_touch new_col
<dbl> <dbl> <dbl> <int> <dbl>
1 NA NA NA 1 NA
2 1 NA 0 2 1
3 2 3 0 3 5
This is what I got:
Error in `mutate_cols()`:
! Problem with `mutate()` column `new_col`.
i `new_col = test %>% select(starts_with("var")) %>% ...`.
x unused argument (rowSums(across(.), na.rm = T))
Caused by error in `ifelse()`:
! unused argument (rowSums(across(.), na.rm = T))
CodePudding user response:
One option would be:
library(dplyr)
test %>%
mutate(new_col = ifelse(
if_all(starts_with("var"), is.na),
NA,
rowSums(across(starts_with("var")), na.rm = TRUE)))
#> # A tibble: 3 × 5
#> var1 var2 var3 do_not_touch new_col
#> <dbl> <dbl> <dbl> <int> <dbl>
#> 1 NA NA NA 1 NA
#> 2 1 NA 0 2 1
#> 3 2 3 0 3 5
Or more in spirit of your try:
test %>%
mutate(select(., starts_with("var")) %>%
transmute(new_col = ifelse(
if_all(.fns = is.na),
NA,
rowSums(across(), na.rm = TRUE))))
#> # A tibble: 3 × 5
#> var1 var2 var3 do_not_touch new_col
#> <dbl> <dbl> <dbl> <int> <dbl>
#> 1 NA NA NA 1 NA
#> 2 1 NA 0 2 1
#> 3 2 3 0 3 5
CodePudding user response:
Does this work?
test %>%
rowwise() %>%
mutate(new_col=sum(across(starts_with('var')), na.rm = T)) %>%
ungroup()
var1 var2 var3 do_not_touch new_col
<dbl> <dbl> <dbl> <int> <dbl>
1 NA NA NA 1 0
2 1 NA 0 2 1
3 2 3 0 3 5
Now if you want to replace the 0 with NA
you can put an ifelse
there
test %>%
rowwise() %>%
mutate(new_col=sum(across(starts_with('var')), na.rm = T)) %>%
ungroup() %>%
mutate(new_col=ifelse(new_col==0, NA, new_col))
var1 var2 var3 do_not_touch new_col
<dbl> <dbl> <dbl> <int> <dbl>
1 NA NA NA 1 NA
2 1 NA 0 2 1
3 2 3 0 3 5