理解R和Tidyverse中的'if()< TRUE>else < FALSE>`vs.`ifelse()` vs `if_else()`

nqwrtyyt  于 2023-07-31  发布在  其他
关注(0)|答案(1)|浏览(90)

我试图确保我理解R中不同的ifelse选项,它们不断地绊倒我。有很多帖子在那里讨论它们,但我还没有看到一个简单的并排比较或解释这三个。有人能为我解释一下吗?

oxosxuxt

oxosxuxt1#

我想回答的是

  1. if(TEST) TRUE else FALSE允许TRUEFALSE响应采用任何类或形式(与if_else()不同).如果TEST是与ifelse()if_else不同的向量,则该方法不起作用
  • ifelse(TEST, TRUE, FALSE)是1)的矢量化版本。如有必要,它将回收TRUEFALSE值。当我想返回一个向量时,我经常会遇到这个问题,在这种情况下,你需要使用一个列表,例如。
  • 命令ifelse(c(TRUE, FALSE), list(c("TRUE1a", "TRUE1b"), c("TRUE2a", "TRUE2b")), list(c("FALSE1a", "FALSE1b"), c("FALSE2a", "FALSE2b"))
  • 将返回list(c("TRUE1a", "TRUE1b"), c("FALSE2a", "FALSE2b"))
  • if_else()要求返回值的类型相同,并且只有返回值的长度为1时才进行回收。

例病例

案例1:if()为真,否则为假

这是baseR的一部分。它的行为受到以下事实的限制:if()仅适用于标量(即长度()== 1的向量)。与if_else()不同,它不检查返回值是否属于同一类型

## These both work
if(is.na(NA)) TRUE else FALSE
if(is.na(NA)) TRUE else "FALSE"

## if() TRUE else FALSE will does not work if the test has a length() > 1 
##
## None of these work
if(is.na(c(NA, 1))) TRUE else  FALSE
if(is.na(NA, 1)) TRUE else c(FALSE, FALSE)
if(is.na(c(NA, 1))) c(TRUE, TRUE) else c(TRUE, FALSE)

## However, if the test value has length() == 1, but return values
## have a length() > 1 it will still work.
## It just returns the appropriate value which happens to be a vector
## This behavior is consistent with this approach not checking that the return values are of the same type or length
if(is.na(NA)) c(TRUE, TRUE) else c(FALSE)
if(is.na(1)) c(TRUE, TRUE) else c(FALSE)

字符串
第二种情况:ifelse()
这是if()TRUE else FALSE和base函数的矢量化版本。类似于标量版本,因为它不确保返回值的类型相同

## These both work
ifelse(is.na(NA), TRUE, FALSE)
## This works here, but doesn't work with `if_else`
ifelse(is.na(NA), TRUE, "FALSE")

## ifelse() will *work* (i.e. not throw an error) if the length of the return values
## is longer than the test vector. However, it has unexpected behavior in that
## it only returns the first value of the relevant vector. This is because the
## test value is only of length 1.
##
## These works but only returns the first element of the return values
## if() TRUE else FALSE would return the entire return value (i.e. a vector)
## if_else() would throw an error.
ifelse(is.na(NA), c(TRUE, TRUE, TRUE), FALSE)
ifelse(is.na(NA), c(TRUE, TRUE, TRUE), c(FALSE, FALSE))

## Unexpectedly (to me anyway) if for every element in the test vector there is
## a corresponding element return vector, it will return that element. I can see
## how this is consistent with R's default recycling behavior
##
## This works and returns the first and second elements of the TRUE vector
ifelse(is.na(c(NA, NA)), c(TRUE, NA), FALSE)

## This works and recycles the TRUE vector
ifelse(is.na(c(NA, 1)), TRUE, FALSE)
## This works as is a more complex illustration of recycling
ifelse(is.na(c(NA, NA, NA, NA)), c(TRUE, NA), FALSE)

案例3:if_else()

tidyverse函数要求两个返回变量的类型相同。这就是为什么它在错误消息中显示“无法合并...”

## This works
if_else(is.na(NA), TRUE, FALSE)
## This doesn't
if_else(is.na(NA), TRUE, "FALSE")

## if_else() will recycle the TRUE and FALSE values based on the size of the TEST value
## However, it will only recycle the return values if it is of length 1.  As a result, it won't work if the length of either return values is > 1, but < length(TEST).
##
## This works
if_else(is.na(c(NA, 1)), TRUE, FALSE)
## This does too, the TRUE case is recycled
if_else(is.na(c(NA, NA)), TRUE, c(FALSE, FALSE))
## This doesn't work since the TRUE cases is longer than the test cases
if_else(is.na(c(NA, 1)), c(TRUE, TRUE, TRUE), FALSE)

相关问题