user2499554
user2499554

Reputation: 1

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

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?

Upvotes: 0

Views: 291

Answers (2)

akrun
akrun

Reputation: 887118

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)

Upvotes: 2

GuedesBF
GuedesBF

Reputation: 9858

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

Upvotes: 3

Related Questions