代码之家  ›  专栏  ›  技术社区  ›  gaut

在R中,返回相等(包括NA)的函数

r
  •  0
  • gaut  · 技术社区  · 1 年前

    在R中,我试图创建一个函数,如果值相等或都为NA,则该函数将返回true。

    is.equal <- `%==%` <- function(x,y, vect=T) {
      res <- ifelse(is.na(x),is.na(y),ifelse(is.na(y),is.na(x),x==y))
      if(!vect){
        res <- all(res)
      }
      return(res)
    }
    
    c("a","b") %==% "a" #[1] TRUE TRUE
    "a" %==% c("a", "b") #[1] TRUE
    c("a","b") == "a" #[1]  TRUE FALSE
    

    我做错了什么,让这个函数只考虑向量的第一个元素?我希望得到与相同的结果 ==


    注1:似乎回收并没有像我预期的那样应用

    > 1:5 %==% 3
    [1] FALSE FALSE FALSE FALSE FALSE
    

    然而

    > 1:5 %==% rep(3,5)
    [1] FALSE FALSE  TRUE FALSE FALSE
    

    注意2:这个版本的函数显式回收,并按预期工作,但我仍然想知道是什么导致了第一个版本中的这种行为:

    is.equal <- `%==%` <- function(x,y, vect=T) {
      samelength <- length(x) == length(y)
      if(!samelength) {
        maxlength <- max(length(x), length(y))
        minlength <- min(length(x), length(y))
        if(minlength==1) {
          if(length(x) == maxlength) {
            y <- rep(y, maxlength)
          } else {
            x <- rep(x, maxlength)
          }
        } else stop('recycling of non-unit vectors disallowed cause bug')
        
      }
      
      res <- ifelse(is.na(x),is.na(y),ifelse(is.na(y),is.na(x),x==y))
      if(!vect){
        res <- all(res)
      }
      return(res)
    }
    > c("a","b") %==% "a"
    [1]  TRUE FALSE
    > "a" %==% c("a", "b")
    [1]  TRUE FALSE
    > c("a","b") == "a"
    [1]  TRUE FALSE
    > 1:5 %==% rep(3,5)
    [1] FALSE FALSE  TRUE FALSE FALSE
    

    对此很好奇

    0 回复  |  直到 1 年前
        1
  •  4
  •   zephryl    1 年前

    你说得对,这是一个回收问题。根据文档,“ ifelse 返回一个值 形状与相同 test ”(我的重点)。换句话说 yes no 可以回收到的长度 测验 , 测验 回收以匹配更长的 。所以如果 测验 长度为1,它只取的第一个值 .

    以下实现更简单,不依赖于 ifelse() ,并按预期工作:

    is.equal <- `%==%` <- function(x, y, vect = T) {
      res <- (is.na(x) & is.na(y)) | (!is.na(x) & !is.na(y) & x == y)
      if (!vect) res <- all(res)
      res
    }
    
    c("a","b") %==% "a"  # TRUE FALSE
    "a" %==% c("a", "b") # TRUE FALSE
    c("a", NA) %==% NA   # FALSE TRUE
    NA %==% c("a", NA)   # FALSE TRUE