【问题标题】:How can I ignore NA's across multiple columns in an if else statement in R?如何在 R 中的 if else 语句中忽略跨多个列的 NA?
【发布时间】:2020-09-17 15:19:41
【问题描述】:

我有一个如下所示的数据框:

     a    b   c   d
10 yes      yes yes yes
11 yes      yes yes yes
12 yes      yes yes yes
13 yes      yes yes yes
14 no      <NA>  no  no
15 no      <NA>  no  no
16 no      <NA>  no  no
17 no      <NA>  no  no
18 no      <NA>  no  no
19 no      <NA>  no  no
20 no      <NA>  no  no

我有一个 if else 语句,它根据对所有先前列的答案是“是”还是“否”来创建一个值为 1,0 的新列。但是,我的代码不考虑 NA。 这是我使用的代码:

y <- x %>%
  mutate(
    health_ever = ifelse(
      e == 'yes    ' |
        b == 'yes' |
        c == 'yes' |
        d == 'yes',
      1,
      0
    )
  )

这里是重现它的代码:

x<-structure(
  list(
    a = structure(
      c(6L, 6L, 6L, 6L, 7L, 7L,
        7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy respondent       ",
        "refusal",
        "don't know",
        "yes    ",
        "no     "
      ),
      class = "factor"
    ),
    b = structure(
      c(6L, 6L, 6L, 6L, NA, NA, NA, NA, NA,
        NA, NA),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    ),
    c = structure(
      c(6L,
        6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    ),
    d = structure(
      c(6L, 6L,
        6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L),
      .Label = c(
        "missing",
        "inapplicable",
        "proxy",
        "refusal",
        "don't know",
        "yes",
        "no"
      ),
      class = "factor"
    )
  ),
  row.names = 10:20,
  class = "data.frame"
)

如何更改我的代码以忽略任何 NA,以便根据其他列仍然给出 1,0。这是我想要的输出:

     a            b        c        d            e
1   yes          yes      yes      yes           1
2   yes          yes      yes      yes           1
3   yes          yes      yes      yes           1
4   yes          yes      yes      yes           1
5   no          <NA>       no       no           0
6   no          <NA>       no       no           0
7   no          <NA>       no       no           0
8   no          <NA>       no       no           0

【问题讨论】:

    标签: r if-statement dplyr


    【解决方案1】:

    在逻辑矩阵上使用rowSums 可以返回每行中NA 的计数。如果返回 0,则表示该行中没有 NA。这可以通过否定 (!) 将 0 更改为 TRUE 并将所有其他值更改为 FALSE 来转换为逻辑。然后使用as.integer+ 将其强制转换为二进制,即TRUE =&gt; 1FALSE =&gt; 0

    x$e <- +(!rowSums(is.na(x)))
    

    基于 OP 的代码,它正在检查“是”值,这也可以通过 rowSums 完成

    x$e <- +(rowSums(x == 'yes', na.rm = TRUE) > 0)
    

    即计算每行中的“是”值,使用na.rm = TRUE 删除NA,通过检查计数是否大于0 转换为逻辑值,并使用+ 将其强制转换为二进制

    如果我们要检查所有列是否为“是”

    x$e <- +(rowSums(x == 'yes', na.rm = TRUE) == ncol(x))
    
     
    

    -输出

    x
    #         a    b   c   d e
    #10 yes      yes yes yes 1
    #11 yes      yes yes yes 1
    #12 yes      yes yes yes 1
    #13 yes      yes yes yes 1
    #14 no      <NA>  no  no 0
    #15 no      <NA>  no  no 0
    #16 no      <NA>  no  no 0
    #17 no      <NA>  no  no 0
    #18 no      <NA>  no  no 0
    #19 no      <NA>  no  no 0
    #20 no      <NA>  no  no 0
    

    在 OP 的代码中,e == 'yes ' 中有一个前导空格,并且“e”不是初始数据集中的列。也许是'a'

    【讨论】:

    • 我如何在我的原始 if else 代码中包含这个?我不想完全删除我的 NA 行
    • @H.B 它没有删除行。它正在创建一个新列“e”
    • @H.B 我更新了帖子。请检查是否有效。嵌套的ifelse 效率会降低
    • 感谢您的回答!如果我的行包含一些带有 Yes 的列,然后是 N/A 的行,则此代码还会返回一个填充为 0 的 e 列。有没有办法改变它?
    • @H.B 您希望条件为| 还是&amp;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-16
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多