【问题标题】:R: case_when producing unexpected "NA" with dplyr mutateR:case_when 使用 dplyr mutate 产生意外的“NA”
【发布时间】:2019-03-01 15:04:55
【问题描述】:

我有以下用户定义函数

vareas1 <- function(a, b, c) {
  case_when(a == 1 ~ "top",
            b == 1 ~ "left",
            c == 1 ~ "right",
            near(a, 1/3) && near(b, 1/3) && near(c, 1/3) ~ "centre"
  )
}

test2 &lt;- vareas1(1/3, 1/3, 1/3)

正确评估为

[1] "centre.

但是,当通过 dplyr 的 mutate 应用它时,它有时会产生 NA。示例如下:

test1 <- data.frame("a" = c(1, 0, 0, 1/3),
                "b" = c(0, 1, 0, 1/3), 
                "c" = c(0, 0, 1, 1/3)) %>% mutate(area1 = vareas1(a, b, c))

这会导致:

          a         b         c area1
1 1.0000000 0.0000000 0.0000000   top
2 0.0000000 1.0000000 0.0000000  left
3 0.0000000 0.0000000 1.0000000 right
4 0.3333333 0.3333333 0.3333333  <NA>

第 [4] 行中的 NA 而不是结果“中心”是出乎意料的,我不明白它来自哪里。

我认为这可能是由于 a、b 和 c 列的类,我调整了函数

  vareas1_int <- function(a, b, c) {
            case_when(a == as.integer(1 * 10e6) ~ "top",
                      b == as.integer(1 * 10e6) ~ "left",
                      c == as.integer(1 * 10e6) ~ "right",
                      near(a, as.integer(1/3 * 10e+6) && 
                      near(b, as.integer(1/3 * 10e+6)) && 
                      near(c, as.integer(1/3 * 10e+6))) ~ "centre"
  )
}

并将a、b、c改为拟合整数:

test1 <- test1 %>%
mutate(a_mil = as.integer(a * 10e+6),
     b_mil = as.integer(b * 10e+6),
     c_mil = as.integer(c * 10e+6))

但结果是一样的:

      a         b         c area1    a_mil    b_mil    c_mil area_int
1 1.0000000 0.0000000 0.0000000   top 10000000        0        0      top
2 0.0000000 1.0000000 0.0000000  left        0 10000000        0     left
3 0.0000000 0.0000000 1.0000000 right        0        0 10000000    right
4 0.3333333 0.3333333 0.3333333  <NA>  3333333  3333333  3333333     <NA>

感谢您的帮助!

(这个类似的post 没有涵盖我的问题。)

【问题讨论】:

  • 不确定&amp;&amp; 是否被矢量化,有什么理由不使用&amp;?不要认为case_when这里有什么问题,只是运营商的问题。
  • @arg0naut 可能是对的。有些帖子已经处理了&amp;&amp;&amp; 之间的区别(here 的一个)。
  • arg0naut 是对的,请参阅?"&amp;",特别是 Details 部分的第二句。我敢肯定那里有一个很好的骗局,但@camille 的并不完全是——它专注于一个奇怪的情况,其中一个输入的长度为 0.... 太糟糕了,很难在 SO 中搜索符号.
  • @Gregor 是的,绝对不是骗子,但我喜欢&amp;&amp; 短路的解释。 Here 是更常见问题类型的帖子。 (另外,我在搜索词中使用了"&amp;&amp;",带有引号,以匹配符号,但仍然不是最好的)
  • 是的,它们是很好的问题,有趣且相关,但正如你所说,不是骗子。感谢您的报价提示,这非常方便!

标签: r na dplyr


【解决方案1】:

您需要&amp; 而不是&amp;&amp; 才能使您的函数与向量一起使用。

library(tidyverse)

vareas1 <- function(a, b, c) {
  case_when(a == 1 ~ "top",
    b == 1 ~ "left",
    c == 1 ~ "right",
    near(a, 1/3) & near(b, 1/3) & near(c, 1/3) ~ "centre"
  )
}

data.frame("a" = c(1, 0, 0, 1/3),
  "b" = c(0, 1, 0, 1/3), 
  "c" = c(0, 0, 1, 1/3)) %>% mutate(area1 = vareas1(a, b, c))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 2018-05-28
    • 2016-01-10
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    相关资源
    最近更新 更多