Làm thế nào để bắt số nguyên (0)?


136

Giả sử chúng ta có một tuyên bố tạo ra integer(0), ví dụ

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

Cách an toàn nhất để nắm bắt điều này là gì?


Tôi không thích ý tưởng coi nó là một lỗi - trên thực tế, chính sách của R không làm sập một số đối tượng trống nhất định giúp tránh nhiều luồng phục hồi lỗi và do đó dẫn đến mã sạch hơn nhiều.
mbq

20
Đừng dùng cái nào.
hadley

1
Bạn có thể kiểm tra với any. Nó sẽ trả về FALSE cho một trong hai which(1:3==5)hoặc cho 1:3==5.
IRTFM

@BondedDust Tôi đã cố gắng tìm integer(0), mà tôi đã tạo ra bằng cách sử dụng whichlàm ví dụ.
Roman Luštrik

6
Tôi biết điều này đã cũ, nhưng bạn có thể, hadley, xin vui lòng phác thảo tại sao không sử dụng which? Điều này sẽ rất hữu ích cho tôi để tránh mã xấu.
Xương rồng

Câu trả lời:


162

Đó là cách của R in một vectơ có độ dài bằng không (một số nguyên), vì vậy bạn có thể kiểm tra ađộ dài 0:

R> length(a)
[1] 0

Nó có thể là đáng suy nghĩ lại chiến lược bạn đang sử dụng để xác định yếu tố mà bạn muốn, nhưng không có chi tiết cụ thể hơn nữa rất khó để đề nghị một chiến lược thay thế.


19

Nếu nó đặc biệt là số nguyên có độ dài bằng không , thì bạn muốn một cái gì đó như

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

Kiểm tra nó với:

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

Bạn cũng có thể sử dụng assertivecho việc này.

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
Bạn chỉ có thể sử dụng !length(x)chứ không phảilength(x)==0
James

3
@James. Đúng, nhưng tôi không nghĩ có nhiều vấn đề về hiệu suất, và length(x) == 0Lđọc rõ hơn cho tôi.
Bông Richie

@RichieC Bông. Có gì với 0L so với 0? Tôi đã thử googling nó, nhưng tôi không tìm thấy bất cứ điều gì có liên quan. Xin lỗi về sự cần thiết.
eenblam

2
@Ben: Việc thêm một Lhậu tố vào một số làm cho R lưu nó dưới dạng một số nguyên chứ không phải là một giá trị dấu phẩy động. Xem, ví dụ: cran.r-project.org/doc/manuals/R-lang.html#Constants
Richie Cotton

Cảm ơn! Nó đã tiết kiệm thời gian của tôi.
Andrii

12

Có thể ngoài chủ đề, nhưng R có hai hàm đẹp, nhanh và trống để giảm các vectơ logic - anyall:

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

1
Vâng, sẽ rất tuyệt nếu có một cái gì đó như is.empty, vì một số chức năng trở lại integer(0)thay vì NAhoặc NULL. Nhưng bây giờ cách của bạn là đơn giản nhất, và hoạt động khôn ngoan, đó là một lợi thế lớn hơn length(a).
Ufos

7

Lấy cảm hứng từ câu trả lời của Andrie, bạn có thể sử dụng identicalvà tránh mọi vấn đề thuộc tính bằng cách sử dụng thực tế rằng đó là tập hợp trống của lớp đối tượng đó và kết hợp nó với một thành phần của lớp đó:

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

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

Hay nói chung hơn:

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

Đây không phải là câu trả lời đơn giản nhất, nhưng cho đến nay là đơn giản và an toàn nhất cho người mới bắt đầu.
JASC

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

Về ý nghĩ thứ hai tôi nghĩ cái nào đẹp hơn 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'") 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.