if-else vs ifelse com listas

Por que a construção if-else e a function ifelse () se comportam de maneira diferente?

mylist <- list(list(a=1, b=2), list(x=10, y=20)) l1 <- ifelse(sum(sapply(mylist, class) != "list")==0, mylist, list(mylist)) l2 <- if(sum(sapply(mylist, class) != "list") == 0){ # T: all list elements are lists mylist } else { list(mylist) } all.equal(l1,l2) # [1] "Length mismatch: comparison on first 1 components" 

if ( cond) { yes } else { no } é uma estrutura de controle. Ele foi projetado para efetuar a programação de garfos em vez de processar uma sequência. Acho que muitas pessoas vêm do SPSS ou do SAS cujos autores escolheram “IF” para implementar a atribuição condicional dentro de suas funções DATA ou TRANSFORM e, portanto, esperam que R se comporte da mesma forma, enquanto R veio de uma tradição de programação. Os loops implícitos de R são incorporados às muitas funções vetorizadas (incluindo ifelse ).

ifelse usa uma expressão que constrói um vetor de valores lógicos como seu primeiro argumento. O segundo e o terceiro argumentos precisam ser vetores de comprimento igual e o primeiro deles ou o segundo é escolhido. Isso é semelhante aos comandos SPSS / SAS IF que possuem um modo de operação implícito por linha.

Da documentação do ifelse:

  'ifelse' returns a value with the same shape as 'test' which is filled with elements selected from either 'yes' or 'no' depending on whether the element of 'test' is 'TRUE' or 'FALSE'. 

Portanto, sua input tem comprimento um, então a saída é truncada para o comprimento 1.

Você também pode ver isso ilustrado com um exemplo mais simples:

 ifelse(TRUE, c(1, 3), 7) # [1] 1 

Por algum motivo isso é marcado como uma duplicata de Por que ifelse () retorna saída de valor único?

Então, um trabalho em torno dessa questão é:

 a=3 yo <- ifelse(a==1, 1, list(c(1,2))) yo[[1]]