Como capturar inteiro (0)?

136

Digamos que temos uma declaração que produz integer(0), por exemplo

 a <- which(1:3 == 5)

Qual é a maneira mais segura de entender isso?

Roman Luštrik
fonte
Não gosto da idéia de tratá-lo como um erro - na verdade, a política de R de não recolher certos objetos vazios ajuda a evitar muitos fluxos de recuperação de erros e, portanto, leva a um código muito mais limpo.
MBq
20
Não use qual.
Hadley
1
Você pode testar com any. Ele retornará FALSE para um which(1:3==5)ou para 1:3==5.
IRTFM 18/06/2014
@BondedDust que estava tentando encontrar integer(0), que produzi usando whichcomo exemplo.
Roman Luštrik
6
Sei que isso é antigo, mas você poderia, Hadley, por favor, explique por que não usar which? Isso seria muito útil para evitar código incorreto.
Cactus

Respostas:

162

Essa é a maneira de R imprimir um vetor de comprimento zero (um inteiro), para que você possa testar o acomprimento 0:

R> length(a)
[1] 0

Pode valer a pena repensar a estratégia que você está usando para identificar quais elementos você deseja, mas sem mais detalhes específicos, é difícil sugerir uma estratégia alternativa.

Gavin Simpson
fonte
19

Se for especificamente inteiros com comprimento zero , você deseja algo como

is.integer0 <- function(x)
{
  is.integer(x) && length(x) == 0L
}

Verifique com:

is.integer0(integer(0)) #TRUE
is.integer0(0L)         #FALSE
is.integer0(numeric(0)) #FALSE

Você também pode usar assertivepara isso.

library(assertive)
x <- integer(0)
assert_is_integer(x)
assert_is_empty(x)
x <- 0L
assert_is_integer(x)
assert_is_empty(x)
## Error: is_empty : x has length 1, not 0.
x <- numeric(0)
assert_is_integer(x)
assert_is_empty(x)
## Error: is_integer : x is not of class 'integer'; it has class 'numeric'.
Richie Cotton
fonte
3
Você poderia simplesmente usar !length(x)ao invés de #length(x)==0
James
3
@James. É verdade, mas acho que não há muito problema de desempenho de qualquer maneira, e ele me length(x) == 0Llê com mais clareza.
Richie Cotton
@RichieCotton. O que há com 0L em vez de 0? Eu tentei pesquisar no Google, mas não estou encontrando nada relevante. Desculpe pela necromancia.
eenblam
2
@ Ben: A adição de um Lsufixo a um número faz com que R o armazene como um número inteiro em vez de um valor de ponto flutuante. Veja, por exemplo, cran.r-project.org/doc/manuals/R-lang.html#Constants
Richie Cotton,
Obrigado! Isso economizou meu tempo.
187 Andrii
12

Talvez fora de tópico, mas o R possui duas funções agradáveis, rápidas e com reconhecimento de vazio para reduzir vetores lógicos - anye all:

if(any(x=='dolphin')) stop("Told you, no mammals!")
mbq
fonte
1
Sim, seria ótimo se houvesse algo como is.empty, porque algumas funções retornam em integer(0)vez de NAou NULL. Mas, por enquanto, seu caminho é o mais direto e funciona em vetor, o que é uma grande vantagem length(a).
Ufos
7

Inspirado na resposta de Andrie, você pode usar identicale evitar problemas de atributo usando o fato de que é o conjunto vazio dessa classe de objeto e combiná-lo com um elemento dessa classe:

attr(a,"foo")<-"bar"

> identical(1L,c(a,1L))
[1] TRUE

Ou mais geralmente:

is.empty <- function(x, mode=NULL){
    if (is.null(mode)) mode <- class(x)
    identical(vector(mode,1),c(x,vector(class(x),1)))
}

b <- numeric(0)

> is.empty(a)
[1] TRUE
> is.empty(a,"numeric")
[1] FALSE
> is.empty(b)
[1] TRUE
> is.empty(b,"integer")
[1] FALSE
James
fonte
Esta não é a resposta mais simples, mas de longe a mais simples e segura para iniciantes.
JASC
7
if ( length(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
#[1] "nothing returned for 'a'"

Pensando bem, acho que alguma é mais bonita que length(.):

 if ( any(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
 if ( any(a <- 1:3 == 5 ) ) print(a)  else print("nothing returned for 'a'") 
IRTFM
fonte