R:一次根据一列中的条件将整行推送到 NA

R: Pushing entire row to NA based on condition in one column at a time

假设 df:

A   B   C   D   E   F
1   10  NA  10  NA  10
10  NA  10  1   10  10
10  1   1   NA  NA  NA
10  10  NA  10  10  10
10  NA  10  10  1   10

我想做的是遍历列以检查具有以下条件的每一行的值:

...随后,循环列中的行与相应条件匹配,整行将被推送到 NA

期望的结果:

A   B   C   D   E   F
NA  NA  NA  NA  NA  NA
10  NA  10  1   10  10
NA  NA  NA  NA  NA  NA
NA  NA  NA  NA  NA  NA
NA  NA  NA  NA  NA  NA

我尝试对其中一列执行此操作:

df[df$A<5, ] <- NA

然而这导致了

的错误
Error in `[<-.data.frame`(`*tmp*`, df$A < 5, , value = NA) : 
  missing values are not allowed in subscripted assignments of data frames

请指教

您可以在对不需要的行进行子集化后直接分配 NA

df[with(df,A<5 | C<3 | E<7 | F<2 |
           is.na(A) | is.na(C) | is.na(E) | is.na(F)),] <- NA
df
#   A  B  C  D  E  F
#1 NA NA NA NA NA NA
#2 10 NA 10  1 10 10
#3 NA NA NA NA NA NA
#4 NA NA NA NA NA NA
#5 NA NA NA NA NA NA

方法是为每一行的每个条件创建一个逻辑向量,然后将它们与 |(或)组合。然后,您可以使用该逻辑向量对 df 进行子集化,以仅用 NA.

替换满足条件的行

使用 with 让您不必输入 df$ 8 次。


根据您的真实数据中有多少条件,您可以使用 Reduce 使其更紧凑,但也许不能:

df[with(df,Reduce(`|`,c(list(A<5, C<3, E<7, F<2),
                        lapply(list(A,C,E,F),is.na)))),] <- NA

你可以使用一些tidyverse操作

library(dplyr)

df_example <- data.table::fread("A   B   C   D   E   F
1   10  NA  10  NA  10
10  NA  10  1   10  10
10  1   1   NA  NA  NA
10  10  NA  10  10  10
10  NA  10  10  1   10")

df_example %>%
  mutate(across(everything(), ~ as.numeric(.x))) %>%
  rowwise() %>%
  mutate(exclude = any(c_across(c(A,C,E,F)) %>% is.na() | A < 5 | C < 3 | E < 7 | F < 2)) %>%
  mutate(across(everything(), .fns = ~ ifelse(exclude == TRUE, yes = NA, .x))) %>%
  select(-exclude) %>%
  ungroup()
#> # A tibble: 5 x 6
#>       A     B     C     D     E     F
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1    NA    NA    NA    NA    NA    NA
#> 2    10    NA    10     1    10    10
#> 3    NA    NA    NA    NA    NA    NA
#> 4    NA    NA    NA    NA    NA    NA
#> 5    NA    NA    NA    NA    NA    NA