R:dplyr突变产生意外“NA”时的情况

R:dplyr突变产生意外“NA”时的情况,r,dplyr,na,mutate,R,Dplyr,Na,Mutate,我有以下用户定义的函数 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" ) } 这导致: a b

我有以下用户定义的函数

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"
  )
}
这导致:

          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>
谢谢你的帮助

这个类似的问题不包括我的问题。

为了使函数与向量一起工作,您需要&而不是&

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))
您需要&而不是&&以使函数使用向量

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))

不确定&&是否已矢量化,是否有不使用&的原因?不要认为case_有什么问题,这只是运算符的问题。@arg0naut可能是对的。有些帖子已经讨论了&and&&one之间的区别。arg0naut是正确的,请参见?&,特别是详细信息部分的第二句。我肯定有一个很好的复制品,但是@camille's不是很好——它关注的是一个奇怪的情况,其中一个输入是长度0。。。。太糟糕了,搜索符号太困难了。@Gregor true,绝对不是傻瓜,但我喜欢对&&短路的解释这是一种更常见的帖子。仅供参考,我在搜索词中使用了&&和引号来匹配符号,但仍然不是最好的。是的,它们是很好的问题,有趣且相关,但正如你所说,不是重复。谢谢你的报价提示,非常方便!不确定&&是否已矢量化,是否有不使用&的原因?不要认为case_有什么问题,这只是运算符的问题。@arg0naut可能是对的。有些帖子已经讨论了&and&&one之间的区别。arg0naut是正确的,请参见?&,特别是详细信息部分的第二句。我肯定有一个很好的复制品,但是@camille's不是很好——它关注的是一个奇怪的情况,其中一个输入是长度0。。。。太糟糕了,搜索符号太困难了。@Gregor true,绝对不是傻瓜,但我喜欢对&&短路的解释这是一种更常见的帖子。仅供参考,我在搜索词中使用了&&和引号来匹配符号,但仍然不是最好的。是的,它们是很好的问题,有趣且相关,但正如你所说,不是重复。谢谢你的报价提示,非常方便!