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

Posted

技术标签:

【中文标题】R:一次根据一列中的条件将整行推送到NA【英文标题】:R: Pushing entire row to NA based on condition in one column at a time 【发布时间】:2020-09-30 16:14:24 【问题描述】:

假设 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 C E F

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

请指教

【问题讨论】:

@Phil 很抱歉打错了字,因为我在编辑过程中不小心通过单击 Enter 发布了问题,我已经修复了错字。但是错误仍然存​​在... 【参考方案1】:

您可以在对不需要的行进行子集化后分配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

【讨论】:

我在dat[-which(!Reduce(`|`, Map(`&lt;`, dat[vars], c(5,3,7,2)))),] &lt;- NA 中有一个类似的Map + Reduce 想法,我认为它与NA 隐含地有效 嗯,我喜欢这个。如果你写了一个答案,我会赞成。 ;) 我不是 100% 确定它适用于所有情况,但我会在有时间的时候返回它。 可能类似于df[-which(Reduce(`&amp;`, Map(`&gt;`,with(df,list(A,C,E,F)),c(5,3,7,2)))),] &lt;- NA【参考方案2】:

您可以使用一些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

【讨论】:

以上是关于R:一次根据一列中的条件将整行推送到NA的主要内容,如果未能解决你的问题,请参考以下文章

R中NA的条件操作

用该列的中位数替换矩阵每一列中的 NA

归一化具有多个条件的数据帧,R

根据其他列中的条件更新一列中的值

小技巧-只删除某一列中含NA的行(R)

如何在不指定每一列的情况下将整行作为参数传递给 Spark(Java)中的 UDF?