Как проверить, определен ли объект (переменная) в R?


294

Я хотел бы проверить, если некоторая переменная определена в R - без получения ошибки. Как я могу это сделать?

Мои попытки (безуспешно):

> is.na(ooxx)
Error: object 'ooxx' not found
> is.finite(ooxx)
Error: object 'ooxx' not found

Спасибо!

Ответы:


449

Вы хотите exists():

R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R> 

3
@Gavin & Dirk, вы так добры друг к другу :) Единственное решение состоит в том, что вы подбрасываете монету (Бернулли с р = 0,5 :-)), который получит согласие! :-)
TMS

29
@tim, если вы внутри функции, отсутствует () - это то, что вам нужно.
Кузен Кокаин

2
Может быть немного сложнее, если проверять элементы списка: stackoverflow.com/q/7719741
TMS

5
как насчет того, что хотел оп - используя имя переменной, а не в кавычках?
Тим

109

Смотрите ?exists, для некоторого определения "... определяется". Например

> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE

7
Вы выиграли на 52 секунды :)
Дирк Эддельбюттель

9
@DirkEddelbuettel Хорошо, если вы будете использовать смехотворно длинные имена объектов ;-)
Гэвин Симпсон

2
хе. Случается со мной все время, когда я проверяю примеры перед публикацией, Гэвин или Джош уже ответили на это.
Майасаура

60

если вы находитесь внутри функции, то вы пропускаете ().

exchequer = function(x) {
    if(missing(x)){
        message("x is missing… :-(")
    }
}

exchequer()
x is missing… :-(

missingоднако работает только для аргументов функции. Вы не можете сделать, foo <- function(x) {missing(x); missing(y)}или вы получите foo(1) > Error in missing(y) : 'missing' can only be used for arguments.
Даннид

46

Как уже отмечали другие, вы ищете exists. Имейте в виду, что использование existsс именами, используемыми базовыми пакетами R, вернет true независимо от того, определили ли вы переменную:

> exists("data")
[1] TRUE

Чтобы обойти это (как указал Bazz; см. ?exists), Используйте inheritsаргумент:

> exists("data", inherits = FALSE)
[1] FALSE

foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE

Конечно, если вы хотите выполнить поиск в пространствах имен прикрепленных пакетов, это также может не сработать:

> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE

Единственное, что я могу придумать, чтобы обойти это - поиск в прикрепленных пакетах, но не в базовых пакетах, - это следующее:

any(sapply(1:(which(search() == "tools:rstudio") - 1L),
           function(pp) exists(_object_name_, where = pp, inherits = FALSE)))

Сравните замену _object_name_с "data.table"( TRUE) против "var"( FALSE)

(конечно, если вы не используете RStudio, я думаю, что первое автоматически подключенное окружение - это "package:stats")


2
Игра вокруг, использование аргументов, inherits = FALSEкажется, изолирует вещи в глобальной среде. Это звучит правильно?
CJB

1
@ Базз, ты прав; Я отредактировал это в ответ.
MichaelChirico

2
Этот комментарий должен быть выше, так как я использую переменную с именем «data», просто использование существующего изначально доставило мне некоторые проблемы.
МЗМ

25

Если вы не хотите использовать кавычки, вы можете использовать deparse(substitute())трюк, который я нашел в разделе примеров ?substitute:

is.defined <- function(sym) {
  sym <- deparse(substitute(sym))
  env <- parent.frame()
  exists(sym, env)
}

is.defined(a)
# FALSE
a <- 10
is.defined(a)
# TRUE

1
Вы также можете forceили оценить это в функции, как это:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
chinsoon12

1

Могут быть ситуации, в которых вы точно не знаете имя переменной, которую вы ищете, например, когда массив результатов был создан системой массового обслуживания. Возможно, к ним можно обратиться с помощью «ls» и его аргумента «pattern», который ожидает регулярное выражение.

Функция «существует» может быть переопределена таким образом, как

exists <-function(variablename) {
   #print(ls(env=globalenv()))
   return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}

При подготовке этого ответа я был немного удивлен необходимостью спецификации среды при вызове ls () из функции. Итак, спасибо вам за это, stackoverflow! Есть также атрибут "all.names", который я должен был установить в true, но пропустить.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.