I am trying to figure out a clean way to add multiple new columns corresponding to multiple existing columns all at once in R. I want each new column cell to be a 0 if the corresponding cell in the corresponding column is an NA value, or a 1 if the corresponding cell has any other value (see example tables below).
I have been able to accomplish this by creating the new columns first, then with a messy which function and a loop. I was wondering if there was a clean way to do this and add in all the new columns with values at once.
Start data
| A | B |
|---|---|
| 5 | NA |
| NA | 4 |
After function is applied
| A | B | A New | B New |
|---|---|---|---|
| 5 | NA | 1 | 0 |
| NA | 4 | 0 | 1 |
CodePudding user response:
In base R,
df[paste0(names(df), 'new')] <- (!is.na(df))
df
# A B Anew Bnew
#1 5 NA 1 0
#2 NA 4 0 1
!is.na(df) gives you logical values (TRUE for non-NA values and FALSE for NA values). Adding at the beginning changes the logical values to integer values (TRUE = 1, FALSE = 0).
CodePudding user response:
With tidyverse, you can use across then apply a function to all columns (i.e., everything()), or you could specify select columns as well. Then, I use .names to create the two new columns.
library(tidyverse)
df %>%
mutate(across(everything(), ~ifelse(is.na(.x), 0,1), .names = "{col} New"))
Output
A B A New B New
1 5 NA 1 0
2 NA 4 0 1
Data
df <- structure(list(A = c(5L, NA), B = c(NA, 4L)),
class = "data.frame", row.names = c(NA, -2L))
