Pergunta

Eu achei as declarações Ifelse de R muito úteis de tempos em tempos. Por exemplo:

ifelse(TRUE,1,2)
# [1] 1
ifelse(FALSE,1,2)
# [1] 2

Mas estou um pouco confuso com o seguinte comportamento.

ifelse(TRUE,c(1,2),c(3,4))
# [1] 1
ifelse(FALSE,c(1,2),c(3,4))
# [1] 3

Esta é uma opção de design acima do meu paygrade?

Foi útil?

Solução

A documentação para ifelse estados:

ifelse retorna um valor com a mesma forma que test que é preenchido com elementos selecionados de qualquer yes ou no dependendo se o elemento de test é TRUE ou FALSE.

Como você está passando pelos valores de teste do comprimento 1, você está obtendo resultados do comprimento 1. Se você passar por vetores de teste mais longos, obterá resultados mais longos:

> ifelse(c(TRUE, FALSE), c(1, 2), c(3, 4))
[1] 1 4

Então ifelse destina -se ao objetivo específico de testar um vetor de booleanos e devolver um vetor do mesmo comprimento, preenchido com elementos retirados do (vetor) yes e no argumentos.

É uma confusão comum, por causa do nome da função, para usá -lo quando você realmente quer apenas um normal if () {} else {} construção em vez disso.

Outras dicas

Aposto que você quer um simples if declaração em vez de ifelse - em R, if Não é apenas uma estrutura de fluxo de controle, ele pode retornar um valor:

> if(TRUE) c(1,2) else c(3,4)
[1] 1 2
> if(FALSE) c(1,2) else c(3,4)
[1] 3 4

Observe que você pode contornar o problema se atribuir o resultado dentro do ifelse:

ifelse(TRUE, a <- c(1,2), a <- c(3,4))
a
# [1] 1 2

ifelse(FALSE, a <- c(1,2), a <- c(3,4))
a
# [1] 3 4

Sim, acho que o ifelse () foi realmente projetado para quando você tem um grande vetor longo de testes e deseja mapear cada um de duas opções. Por exemplo, geralmente faço cores para plot () dessa maneira:

plot(x,y, col = ifelse(x>2,  'red', 'blue'))

Se você tivesse um grande vetor longo de testes, mas queria pares para saídas, você poderia usar sapply() ou plyr's llply() Ou algo assim, talvez.

Aqui está uma abordagem semelhante à sugerida por Cath, mas pode funcionar com os vetores pré-atribuídos existentes

É baseado em usar o get() igual a:

a <- c(1,2)
b <- c(3,4)
get(ifelse(TRUE, "a", "b"))
# [1] 1 2

Às vezes o usuário só precisa de um switch declaração em vez de um ifelse. Nesse caso:

condition <- TRUE
switch(2-condition, c(1, 2), c(3, 4))
#### [1] 1 2

(que é outra opção de sintaxe da resposta de Ken Williams)

Use `if`, por exemplo

> `if`(T,1:3,2:4)
[1] 1 2 3

No seu caso, usando if_else a partir de dplyr teria sido útil: if_else é mais rigoroso do que ifelse, e lança um erro para o seu caso:

library(dplyr)
if_else(TRUE,c(1,2),c(3,4))
#> `true` must be length 1 (length of `condition`), not 2
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top