首页 > 解决方案 > R - 在多个列中应用条件忽略 NA

问题描述

假设我有以下数据框:

x <- c(1, 1, 2, 3, 4, 5)
y <- c(1, 1, 1, 3, 4, 5)
z <- c(NA, 1, 1, 3, 4, NA)

要得到:

x  y  z
1  1  NA
1  1  1
2  1  1
3  3  3
4  4  4
5  4  NA

我想得到一个条件语句,如果所有非 NA x、y 和 z 值都等于 1,那么它将被标记为 1,我将如何编写这个脚本?

例如,我想要的是以下内容:

x  y  z  flag1
1  1  NA 1
1  1  1  1
2  1  1  0
3  3  3  0
4  4  4  0
5  4  NA 0

此外,我还想标记是否有任何变量包含 4,忽略 NA,以便我可以得到:

x  y  z  flag1 flag2
1  1  NA 1     0
1  1  1  1     0
2  1  1  0     0
3  3  3  0     0
4  4  4  0     1
5  4  NA 0     1

标签: rif-statementconditional-statements

解决方案


最简单的是rowSums

df$flag <-  +(!rowSums(df != 1, na.rm = TRUE) & !!rowSums(!is.na(df)))
df$flag2 <- +(rowSums(df == 4, na.rm = TRUE) > 0 & !!rowSums(!is.na(df)))

-输出

> df
  x y  z flag flag2
1 1 1 NA    1     0
2 1 1  1    1     0
3 2 1  1    0     0
4 3 3  3    0     0
5 4 4  4    0     1
6 5 4 NA    0     1

tidyverse中,我们可以使用if_allwithif_any来创建这些列

library(dplyr)
df %>%
    mutate(flag1 = +(if_all(everything(),  ~is.na(.)| . %in% 1)), 
            flag2 = +(if_any(x:z, ~ . %in% 4)))
  x y  z flag1 flag2
1 1 1 NA     1     0
2 1 1  1     1     0
3 2 1  1     0     0
4 3 3  3     0     0
5 4 4  4     0     1
6 5 4 NA     0     1

数据

df <-structure(list(x = c(1, 1, 2, 3, 4, 5), y = c(1, 1, 1, 3, 4, 
4), z = c(NA, 1, 1, 3, 4, NA)), class = "data.frame", row.names = c(NA, 
-6L))

推荐阅读