R 将 "TRUE" 字符串强制为 TRUE 逻辑是怎么回事?

What is going on with R coercing "TRUE" string to TRUE logical?

所以,我发现了这个:

> TRUE == "TRUE"
[1] TRUE
> TRUE == "BOO"
[1] FALSE
> TRUE == "true"
[1] FALSE
> TRUE == "T"
[1] FALSE
> FALSE == "FALSE"
[1] TRUE
> FALSE == "F"
[1] FALSE

根据 logical {base} 的 R 文档:

as.logical attempts to coerce its argument to be of logical type. Character strings c("T", "TRUE", "True", "true") are regarded as true, c("F", "FALSE", "False", "false") as false, and all others as NA.

实际情况是这样的:

> as.logical("T")
[1] TRUE

很明显,TRUE == "T" 发生的事情不是 as.logical 类型的转换。这些 == 比较的行为是否有任何合理的解释?

这是我对它的看法: 来自逻辑比较的文档?"=="

At least one of x and y must be an atomic vector, but if the other is a list R attempts to coerce it to the type of the atomic vector: this will succeed if the list is made up of elements of length one that can be coerced to the correct type. If the two arguments are atomic vectors of different types, one is coerced to the type of the other, the (decreasing) order of precedence being character, complex, numeric, integer, logical and raw.

对我来说,后半部分似乎在这里起作用。 TRUE 被强制转换为 "TRUE",实际比较变为 "TRUE"=="TRUE" 而不是 TRUE==TRUE

T 总是转换为 TRUE 所以 T=="TRUE" 成立。然而,当转换发生 to.character 而不是 to.logical 时,`"T"` 就没有这样的运气了。 .

关于你的问题,我无法想象你会评估 TRUE == "TRUE""TRUE" == TRUE 的场景。例如;采用包装函数,我们可以 运行 所有变量的场景,并通过 as.logical, is.logical, x == TRUE, x == FALSE, x != TRUE 等的测试迭代它们...

我们的测试函数将做的是接受一个输入,并且仅 return 根据 R 函数中的逻辑测试评估为 TRUE 的场景。

f <-function(var){
  do_fun <- list(
    `%s == TRUE` = function(x)x==TRUE,
    `%s == FALSE` = function(x)x == FALSE,
    `as.logical(%s)` = function(x)as.logical(x),
    `is.logical(%s)` = function(x)is.logical(x))

  a <- sapply(names(do_fun), function(i){
    do.call(do_fun[[i]],list(var))
  })
  set_name <- sprintf(names(a),var)
  a <- as.list(a)
  names(a) <- set_name
  a[sapply(a,`[`,1)]

}

测试 TRUE

# from base test to show
> is.logical(TRUE)
[1] TRUE

现在享受我们的测试乐趣

> f(TRUE)
$`TRUE == TRUE`
[1] TRUE

$`as.logical(TRUE)`
[1] TRUE

$`is.logical(TRUE)`
[1] TRUE

作为字符串而不是保留字符

> f("true")
$`as.logical("true")`
[1] TRUE

> f("TRUE")
$`"TRUE" == TRUE`
[1] TRUE

$`as.logical("TRUE")`
[1] TRUE

对于数值,输出逻辑基于输入的评估而不是 class

> f(10.1)
$`as.logical(10.1)`
[1] TRUE

> f(10.1 > 1)
$`TRUE == TRUE`
[1] TRUE

$`as.logical(TRUE)`
[1] TRUE

$`is.logical(TRUE)`
[1] TRUE

> f(1+1)
$`as.logical(2)`
[1] TRUE

更好用isTRUE

> isTRUE 
function (x) 
identical(TRUE, x)
<bytecode: 0x82228c8>
<environment: namespace:base>

> isTRUE("T")
[1] FALSE
> isTRUE(T)
[1] TRUE
> isTRUE(TRUE)
[1] TRUE
> isTRUE("TRUE")
[1] FALSE 
> isTRUE("anything")
[1] FALSE
> isTRUE(1L)
[1] FALSE
> isTRUE(c(TRUE,TRUE))
[1] FALSE
> 
> isTRUE(any(c(TRUE,TRUE)))
[1] TRUE
> isTRUE(all(c(TRUE,TRUE)))
[1] TRUE

> answer <- "yes"
> isTRUE(answer %in% c("Y","Yes","y","yes"))
[1] TRUE
> answer <- "no"
> isTRUE(answer %in% c("Y","Yes","y","yes"))
[1] FALSE
> answer <- c("Y","n")
> isTRUE(answer %in% c("Y","Yes","y","yes"))
[1] FALSE