I have a huge df and a simplified version of my problem is:
A <- c("CA1", "CA2", "CA3", "CA4")
B <- c( 0,1,0,1)
C <- c(1,1,0,0)
df <- data.frame(A, B, C)
I would like all row values that correspond to CA3 and CA4 to change to NA and the resulting df2:
A B C
CA1 0 1
CA2 1 1
CA3 NA NA
CA4 NA NA
Is it possible to do this with base R and dplyr? The code I have adapted but of course isn't working is:
df2 <- df %>% mutate_at(row("CA3", "CA4"), na_if, 0) %>%
mutate_at(row("CA3", "CA4"), na_if, 1)
my error code is: Error in if (as.factor) { : argument is not interpretable as logical
Any ideas on how to generate a code to get the df2 output?
Thank you!
CodePudding user response:
Loop across
the 'B', 'C' column, create the condition where the 'A' value is 'CA3', 'CA4' with %in%
and change the values in case_when
. The default TRUE
condition in case_when
returns NA
if we specify the other condition to return the original column values
library(dplyr)
df2 <- df %>%
mutate(across(B:C, ~ case_when(!A %in% c("CA3", "CA4") ~ .)))
-output
df2
A B C
1 CA1 0 1
2 CA2 1 1
3 CA3 NA NA
4 CA4 NA NA
CodePudding user response:
Accomplishing the same task in base R:
df[df$A %in% c("CA3", "CA4"), c("B", "C")] <- NA
df
A B C
1 CA1 0 1
2 CA2 1 1
3 CA3 NA NA
4 CA4 NA NA
CodePudding user response:
Here is a pivoting alternative:
library(dplyr)
librayr(tidyr)
df %>%
pivot_longer(
cols = -A
) %>%
mutate(value = ifelse(A == "CA3" | A == "CA4", NA, value)) %>%
pivot_wider(
names_from = name
)
A B C
<chr> <dbl> <dbl>
1 CA1 0 1
2 CA2 1 1
3 CA3 NA NA
4 CA4 NA NA