как изменить значения строк на основе информации из другого фрейма данных в R

#r

Вопрос:

У меня есть оригинальный df:

 A <- c("A1", "A2", "A3", "A4")
B <- c(1,0,1,NA)
C <- c(0,1,0,NA)
D <- c(NA, 1, 0, NA)
              
df <- data.frame(A, B, C, D)
 

И мой второй df2:

 A <- c("A2", "A3")
df2 <- data.frame(A)
 

Я хотел бы изменить df_modified, чтобы он выглядел так

 A    B   C   D
A1   1   0   NA
A2   NA  NA  NA
A3   NA  NA  NA 
A4   NA  NA  NA
 

Мой текущий код, который сгенерировал все строки, заполненные NA, является:

 df_modifed <- df %>% mutate(B = case_when(df$A == df2$A ~ NA),
              C = case_when(df$A == df2$A ~ NA),
               D = case_when(df$A == df2$A ~ NA))
 

Как я могу сделать это правильно?

Ответ №1:

В base R , это проще, т. е. укажите логический индекс как row и индекс столбца без первого столбца ( -1 ) и назначьте эти элементы NA

 df[df$A %in% df2$A, -1] <- NA
 

-выход

 > df
   A  B  C  D
1 A1  1  0 NA
2 A2 NA NA NA
3 A3 NA NA NA
4 A4 NA NA NA
 

Или , если мы хотим использовать tidyverse , используйте across

 library(dplyr)
df %>%
   mutate(across(where(is.numeric), ~ case_when(!A %in% df2$A~ .)))
 

-выход

    A  B  C  D
1 A1  1  0 NA
2 A2 NA NA NA
3 A3 NA NA NA
4 A4 NA NA NA
 

Комментарии:

1. Да, похоже на то. Спасибо, ваш код работает!

Ответ №2:

Вот альтернативный dplyr способ:

 bind_rows(df, df2) %>% 
  group_by(A) %>% 
  mutate(across(c(B,C,D), ~first(.)==last(.))*1) %>% 
  distinct()
 
   A         B     C     D
  <chr> <dbl> <dbl> <dbl>
1 A1        1     1    NA
2 A2       NA    NA    NA
3 A3       NA    NA    NA
4 A4       NA    NA    NA