Come catturare intero (0)?


136

Diciamo che abbiamo una dichiarazione che produce integer(0), ad es

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

Qual è il modo più sicuro per catturarlo?


Non mi piace l'idea di trattarlo come un errore - in effetti la politica di R di non far collassare alcuni oggetti vuoti aiuta a evitare molti flussi di recupero degli errori e porta quindi a un codice molto più pulito.
mbq,

20
Non usare quale.
Hadley,

1
Puoi provare con any. Restituirà FALSO per uno which(1:3==5)o per 1:3==5.
IRTFM,

@BondedDust Stavo cercando di trovare integer(0), che ho prodotto usando whichcome esempio.
Roman Luštrik,

6
So che questo è vecchio, ma potresti, Hadley, per favore delineare perché non usarlo which? Questo mi sarebbe molto utile per evitare codici errati.
Cactus,

Risposte:


162

Questo è il modo di R di stampare un vettore di lunghezza zero (uno intero), quindi potresti provarlo a essere di lunghezza 0:

R> length(a)
[1] 0

Potrebbe valere la pena ripensare la strategia che stai usando per identificare quali elementi vuoi, ma senza ulteriori dettagli specifici è difficile suggerire una strategia alternativa.


19

Se si tratta di numeri interi di lunghezza zero , allora vuoi qualcosa di simile

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

Controllalo con:

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

Puoi anche usarlo assertiveper questo.

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'.

3
Potresti semplicemente usare !length(x)piuttosto chelength(x)==0
James il

3
@James. È vero, ma non credo che ci sia un grosso problema di prestazioni in entrambi i casi, e mi length(x) == 0Llegge più chiaramente.
Richie Cotton,

@RichieCotton. Che succede con 0L invece di 0? Ho provato a cercarlo su Google, ma non trovo nulla di rilevante. Mi dispiace per la negromanzia.
eenblam,

2
@Ben: l'aggiunta di un Lsuffisso a un numero fa sì che R lo memorizzi come numero intero anziché come valore in virgola mobile. Vedi, ad esempio, cran.r-project.org/doc/manuals/R-lang.html#Constants
Richie Cotton

Grazie! Mi ha risparmiato tempo.
Andrii,

12

Forse fuori tema, ma R presenta due funzioni carine, veloci e consapevoli del vuoto per ridurre i vettori logici - anye all:

if(any(x=='dolphin')) stop("Told you, no mammals!")

1
Sì, sarebbe fantastico se ci fosse qualcosa di simile is.empty, perché alcune funzioni ritornano integer(0)invece di NAo NULL. Ma per ora la tua strada è la più semplice e funziona in modo vettoriale, il che è un grande vantaggio length(a).
Ufo,

7

Ispirato dalla risposta di Andrie, puoi usare identicaled evitare qualsiasi problema di attributo usando il fatto che è l'insieme vuoto di quella classe di oggetti e combinalo con un elemento di quella classe:

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

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

O più in generale:

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

Questa non è la risposta più semplice, ma di gran lunga la più semplice e sicura per i principianti.
JASC,

7
if ( length(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
#[1] "nothing returned for 'a'"

A pensarci bene, penso che uno sia più bello di 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'") 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.