Bagaimana cara menangkap integer (0)?

136

Katakanlah kita memiliki pernyataan yang menghasilkan integer(0), misalnya

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

Apa cara teraman untuk menangkap ini?

Roman Luštrik
sumber
Saya tidak suka gagasan memperlakukannya sebagai kesalahan - pada kenyataannya kebijakan R tentang tidak runtuh objek kosong tertentu membantu menghindari banyak aliran pemulihan kesalahan, dan dengan demikian mengarah pada kode yang jauh lebih bersih.
mbq
20
Jangan gunakan yang mana.
Hadley
1
Anda bisa mengujinya any. Ini akan mengembalikan FALSE untuk salah satu which(1:3==5)atau untuk 1:3==5.
IRTFM
@BondedDust yang saya coba temukan integer(0), yang saya hasilkan menggunakan whichcontoh.
Roman Luštrik
6
Saya tahu ini sudah tua, tetapi bisakah Anda, Hadley, tolong jelaskan mengapa tidak digunakan which? Ini akan sangat membantu saya untuk menghindari kode yang buruk.
Cactus

Jawaban:

162

Itu adalah cara R untuk mencetak vektor panjang nol (bilangan bulat), sehingga Anda bisa menguji apanjangnya 0:

R> length(a)
[1] 0

Mungkin ada baiknya memikirkan kembali strategi yang Anda gunakan untuk mengidentifikasi elemen mana yang Anda inginkan, tetapi tanpa rincian spesifik lebih lanjut, sulit untuk menyarankan strategi alternatif.

Gavin Simpson
sumber
19

Jika khusus bilangan bulat nol panjang , maka Anda ingin sesuatu seperti

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

Periksa dengan:

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

Anda juga dapat menggunakannya assertiveuntuk ini.

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
sumber
3
Anda bisa menggunakan !length(x)daripadalength(x)==0
James
3
@ James. Benar, tapi saya tidak berpikir ada banyak masalah kinerja, dan length(x) == 0Lmembaca lebih jelas kepada saya.
Richie Cotton
@RichieCotton Ada apa dengan 0L dibandingkan dengan 0? Saya sudah mencoba googling, tetapi saya tidak menemukan sesuatu yang relevan. Maaf tentang necromancy.
eenblam
2
@Ben: Menambahkan Lakhiran ke angka membuat R menyimpannya sebagai bilangan bulat dan bukan nilai floating point. Lihat, misalnya, cran.r-project.org/doc/manuals/R-lang.html#Constants
Richie Cotton
Terima kasih! Ini menghemat waktu saya.
Andrii
12

Mungkin di luar topik, tetapi R menampilkan dua fungsi yang bagus, cepat, dan tanpa sadar untuk mengurangi vektor logis - anydan all:

if(any(x=='dolphin')) stop("Told you, no mammals!")
mbq
sumber
1
Ya, akan lebih bagus jika ada sesuatu seperti is.empty, karena beberapa fungsi kembali, integer(0)bukan NAatau NULL. Tetapi untuk saat ini jalan Anda adalah yang paling mudah, dan bekerja dengan bijaksana yang merupakan keunggulan besar length(a).
Ufos
7

Terinspirasi oleh jawaban Andrie, Anda bisa menggunakan identicaldan menghindari masalah atribut dengan menggunakan fakta bahwa itu adalah himpunan kosong dari kelas objek tersebut dan menggabungkannya dengan elemen kelas itu:

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

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

Atau lebih umum:

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
sumber
Ini bukan jawaban yang paling sederhana, tetapi sejauh ini yang paling sederhana dan paling aman untuk pemula.
JASC
7
if ( length(a <- which(1:3 == 5) ) ) print(a)  else print("nothing returned for 'a'") 
#[1] "nothing returned for 'a'"

Setelah dipikir-pikir saya pikir ada yang lebih indah dari 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
sumber