Applying same operation over columns with same string within column names?

Solution for Applying same operation over columns with same string within column names?
is Given Below:

This may be a very simple question but I feel like I have two different answers that are helpful but are hard to put together. This is also my first question on StackOverflow so here goes:

I have a data frame that is measurements of a chemical process. There are column names like AirValve, PressureValve, OilLevel, PressureLevel etc.
The values in these columns are either NA or a whole number.

For Example:

AirValve <-c(rep(1,3),rep(2,5),rep(3,8),rep(4,4)) PressureLevel<-c(12,NA,NA,15,NA,NA,NA,NA,14,NA,NA,NA,NA,NA,NA,NA,16,NA,NA,NA) df1<-data.frame(AirValve,PressureLevel)

I have to turn all the NAs to 0s, but only in certain columns with the word “Level” in the name.

If it was just df1$PressureLevel I could do:

df1$PressureLevel[is.na(df1$PressureLevel)] <- 0

But there are many other columns with “Level” in the name.

I also know grepl can be used as such:

grepl("Level", names(df1))

but don’t know exactly what it does or how it can be used together with the previous line.

How would I turn NA values to 0 values in only columns that satisfy this grepl condition?

You are looking for the contains()selection helper here.

With dplyr, we can mutate across() columns that contains() the pattern “Level”, and replace()these values with 0.

library(dplyr)

df1 %>% mutate(across(contains("Level"), ~replace(.x, is.na(.x), 0)))

replace() is usually more general and can be used to replace different values. For NAs in particular, we can also use coalesce() or replace_na:

library(dplyr)

df1 %>% mutate(across(contains("Level"), ~coalesce(.x, 0)))

#OR

df1 %>% mutate(across(contains("Level"), replace_na, 0))

output

   AirValve PressureLevel
1         1            12
2         1             0
3         1             0
4         2            15
5         2             0
6         2             0
7         2             0
8         2             0
9         3            14
10        3             0
11        3             0
12        3             0
13        3             0
14        3             0
15        3             0
16        3             0
17        4            16
18        4             0
19        4             0
20        4             0

We can use the same option

nm1 <- grepl("Level", names(df1))
df1[nm1][is.na(df1[nm1])] <- 0

If we want to replace the NA elements with previous non-NA

library(dplyr)
library(tidyr)
df1 %>%
     group_by(x1) %>%
     fill(x2)