Tam sayı (0) nasıl yakalanır?


136

Diyelim biz üreten bir bildirimde bulunmamış demek integer(0), mesela

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

Bunu yakalamanın en güvenli yolu nedir?


Bunu bir hata olarak ele alma fikrinden hoşlanmıyorum - aslında R'nin belirli boş nesneleri daraltmama politikası birçok hata kurtarma akışından kaçınmaya yardımcı oluyor ve bu nedenle çok daha temiz kodlara yol açıyor.
mbq

20
Hangisini kullanma.
hadley

1
İle test edebilirsiniz any. Ya FALSE değerini ya which(1:3==5)da için döndürecektir 1:3==5.
IRTFM

@BondedDust Örnek olarak integer(0)kullanarak ürettiğim bulmaya çalışıyordum which.
Roman Luštrik

6
Bunun eski olduğunu biliyorum, ama sen, hadley, lütfen neden kullanmaman gerektiğini özetleyebilir whichmisin? Kötü kodlardan kaçınmak benim için çok yararlı olur.
Kaktüs

Yanıtlar:


162

Bu, R'nin sıfır uzunluklu bir vektörü (tamsayı) basma şeklidir, böylece a0 uzunluğunun olup olmadığını test edebilirsiniz :

R> length(a)
[1] 0

Hangi öğeleri istediğinizi belirlemek için kullandığınız stratejiyi yeniden düşünmeye değer olabilir , ancak daha ayrıntılı bilgi olmadan alternatif bir strateji önermek zordur.


19

Özellikle sıfır uzunluklu tamsayılarsa ,

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

Şunlarla kontrol et:

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

Bunun için de kullanabilirsiniz assertive.

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
Sadece kullanabilirsiniz !length(x)ziyadelength(x)==0
James

3
@James. Doğru, ama her iki şekilde de bir performans sorunu olduğunu düşünmüyorum ve length(x) == 0Lbana daha net bir şekilde okuyor.
Richie Cotton

@RichieCotton. 0 yerine 0L ile ilgili ne var? Google'ı aramayı denedim, ancak alakalı bir şey bulamıyorum. Büyücülük için özür dilerim.
eenblam

2
@Ben: LBir sayıya sonek eklemek , R'nin onu kayan nokta değeri yerine tamsayı olarak depolamasını sağlar. Bkz. Örneğin cran.r-project.org/doc/manuals/R-lang.html#Constants
Richie Cotton

Teşekkürler! Zamanımı kurtardı.
Andrii

12

Konu dışı olabilir, ancak R mantıksal vektörleri azaltmak için iki güzel, hızlı ve boş farkında fonksiyona sahiptir - anyve all:

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

1
Evet, böyle bir şey olsaydı harika olurdu is.empty, çünkü bazı işlevler veya integer(0)yerine geri döner . Ama şimdilik yolunuz en basit olanıdır ve vektörel olarak çalışır, bu da büyük bir avantajdır . NANULLlength(a)
Ufos

7

Andrie'nin cevabından esinlenerek, identicalherhangi bir nitelik problemini, o nesne sınıfının boş kümesi olduğu gerçeğini kullanarak kullanabilir ve önleyebilirsiniz ve bunu o sınıfın bir öğesiyle birleştirebilirsiniz:

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

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

Veya daha genel olarak:

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

Bu en basit cevap değil, yeni başlayanlar için açık ara en basit ve en güvenli olanı.
JASC

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

İkinci düşünce herhangi biri daha güzel olduğunu düşünüyorum 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'") 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.