Câu trả lời:
Bạn muốn exists()
:
R> exists("somethingUnknown")
[1] FALSE
R> somethingUnknown <- 42
R> exists("somethingUnknown")
[1] TRUE
R>
Xem ?exists
, đối với một số định nghĩa của "... được xác định". Ví dụ
> exists("foo")
[1] FALSE
> foo <- 1:10
> exists("foo")
[1] TRUE
nếu bạn đang ở trong một hàm, thiếu () là những gì bạn muốn.
exchequer = function(x) {
if(missing(x)){
message("x is missing… :-(")
}
}
exchequer()
x is missing… :-(
missing
Tuy nhiên, chỉ hoạt động cho các đối số chức năng. Bạn không thể làm foo <- function(x) {missing(x); missing(y)}
hoặc bạn sẽ nhận được foo(1)
> Error in missing(y) : 'missing' can only be used for arguments
.
Như những người khác đã chỉ ra, bạn đang tìm kiếm exists
. Hãy nhớ rằng việc sử dụng exists
với các tên được sử dụng bởi các gói cơ sở của R sẽ trả về true bất kể bạn có xác định biến hay không:
> exists("data")
[1] TRUE
Để giải quyết vấn đề này (như được chỉ ra bởi Bazz; xem ?exists
), hãy sử dụng inherits
đối số:
> exists("data", inherits = FALSE)
[1] FALSE
foo <- TRUE
> exists("foo", inherits = FALSE)
[1] TRUE
Tất nhiên, nếu bạn muốn tìm kiếm không gian tên của các gói đính kèm, điều này cũng sẽ bị thiếu:
> exists("data.table")
[1] FALSE
require(data.table)
> exists("data.table", inherits = FALSE)
[1] FALSE
> exists("data.table")
[1] TRUE
Điều duy nhất tôi có thể nghĩ ra để giải quyết vấn đề này - để tìm kiếm trong các gói đính kèm nhưng không phải trong các gói cơ sở - là như sau:
any(sapply(1:(which(search() == "tools:rstudio") - 1L),
function(pp) exists(_object_name_, where = pp, inherits = FALSE)))
So sánh thay thế _object_name_
bằng "data.table"
( TRUE
) so với "var"
( FALSE
)
(tất nhiên, nếu bạn không ở trên RStudio, tôi nghĩ môi trường được đính kèm tự động đầu tiên là "package:stats"
)
inherits = FALSE
dường như cô lập mọi thứ trong môi trường toàn cầu. Nghe có đúng không?
Nếu bạn không muốn sử dụng dấu ngoặc kép, bạn có thể sử dụng deparse(substitute())
mẹo mà tôi tìm thấy trong phần ví dụ của ?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
force
hoặc đánh giá nó trong chức năng như thế này:is.defined <- function(sym) class(try(sym, TRUE))!='try-error'
Có thể có những tình huống mà bạn không biết chính xác tên của biến bạn đang tìm, như khi một mảng kết quả được tạo bởi một hệ thống xếp hàng. Chúng có thể được giải quyết bằng "ls" và "mẫu" đối số của nó mong đợi một biểu thức chính quy.
Hàm "tồn tại" có thể được thực hiện lại theo cách đó như
exists <-function(variablename) {
#print(ls(env=globalenv()))
return(1==length(ls(pattern=paste("^",variablename,"$",sep=""),env=globalenv())))
}
Trong khi chuẩn bị câu trả lời này, tôi hơi ngạc nhiên về sự cần thiết của đặc tả môi trường khi gọi ls () từ bên trong một hàm. Vì vậy, cảm ơn bạn vì điều đó, stackoverflow! Ngoài ra còn có một thuộc tính "all.names" mà tôi nên đặt thành đúng nhưng đã bỏ qua.