Як зловити ціле число (0)?


136

Скажімо, у нас є твердження, яке виробляє integer(0), наприклад

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

Який найбезпечніший спосіб цього зрозуміти?


Мені не подобається ідея трактувати це як помилку - адже політика R щодо не згортання певних порожніх об'єктів допомагає уникнути багатьох потоків для відновлення помилок і, таким чином, призводить до набагато більш чистого коду.
mbq

20
Не використовуйте який.
хадлі

1
Ви можете спробувати any. Він поверне FALSE для which(1:3==5)або для 1:3==5.
IRTFM

@BondedDust я намагався знайти integer(0), що я створив, використовуючи whichяк приклад.
Роман Луштрик

6
Я знаю, що це по-старому, але чи не могли б ви, Хадлі, окреслити, чому б не використати which? Це було б дуже корисно для мене, щоб уникнути поганого коду.
Кактус

Відповіді:


162

Це спосіб R надрукувати вектор нульової довжини (ціле число), так що ви можете перевірити наявність aдовжини 0:

R> length(a)
[1] 0

Можливо, варто переосмислити стратегію, яку ви використовуєте, щоб визначити, які елементи ви хочете, але без додаткових конкретних деталей важко запропонувати альтернативну стратегію.


19

Якщо це конкретно цілі нульові цілі , то вам потрібно щось подібне

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

Перевірте це за допомогою:

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

Ви також можете використовувати 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
Ви могли просто використовувати, !length(x)а неlength(x)==0
Джеймс,

3
@James. Щоправда, але я не думаю, що жодного з питань виступу немає, і length(x) == 0Lчитається мені більш чітко.
Річі Коттон

@RichieCotton. Що з 0L на відміну від 0? Я спробував його погуглити, але нічого значущого не знаходжу. Вибачте за некромантичність.
eenblam

2
@Ben: Додавання Lсуфікса до числа змушує R зберігати його як ціле число, а не значення з плаваючою точкою. Дивіться, наприклад, cran.r-project.org/doc/manuals/R-lang.html#Constants
Річі Коттон

Дякую! Це врятувало мій час.
Андрій

12

Можливо поза темою, але R має дві приємні, швидкі та порожні функції, що зменшують логічні вектори - anyі all:

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

1
Так, було б чудово, якби щось було is.empty, бо деякі функції повертаються integer(0)замість NAабо NULL. Але поки ваш шлях найбільш простий і працює векторно, що є великою перевагою перед length(a).
Ufos

7

Натхненний відповіддю Андрі, ви можете використовувати identicalта уникати будь-яких проблем з атрибутами, використовуючи той факт, що це порожній набір цього класу об’єктів та комбінувати його з елементом цього класу:

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

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

Або загалом:

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

Це не найпростіша відповідь, але, безумовно, найпростіша і безпечна для початківців.
JASC

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

По-друге, я думаю, що будь-яке прекрасніше, ніж 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'") 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.