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

问题描述 投票:0回答:1

假设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

我想做的是在列中循环检查每行的值,条件如下:

  • A < 5或NA
  • C < 3或NA
  • E < 7或NA
  • F < 2或NA

......随后,循环列中的行与相应的条件相匹配,整个行将被推送到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

请告知

r loops if-statement variable-assignment na
1个回答
4
投票

你可以直接指定 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

3
投票

你可以用一些 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
© www.soinside.com 2019 - 2024. All rights reserved.