在R语言中,返回包含NA相等的函数

vx6bjr1n  于 2023-04-18  发布在  R语言
关注(0)|答案(1)|浏览(235)

在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

对此相当好奇

hxzsmxv2

hxzsmxv21#

你说得对,这是一个回收问题。根据文档,“ifelse返回一个值**,其形状与test**相同”换句话说,虽然yesno可以被再循环到test的长度,testnot被回收以匹配更长的yesno。因此,如果test的长度为1,则它只接受yesno的第一个值。
下面的实现更简单,不依赖于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

相关问题