Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.6k views
in Technique[技术] by (71.8m points)

r - How to test if list element exists?

Problem

I would like to test if an element of a list exists, here is an example

foo <- list(a=1)
exists('foo') 
TRUE   #foo does exist
exists('foo$a') 
FALSE  #suggests that foo$a does not exist
foo$a
[1] 1  #but it does exist

In this example, I know that foo$a exists, but the test returns FALSE.

I looked in ?exists and have found that with(foo, exists('a') returns TRUE, but do not understand why exists('foo$a') returns FALSE.

Questions

  • Why does exists('foo$a') return FALSE?
  • Is use of with(...) the preferred approach?
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is actually a bit trickier than you'd think. Since a list can actually (with some effort) contain NULL elements, it might not be enough to check is.null(foo$a). A more stringent test might be to check that the name is actually defined in the list:

foo <- list(a=42, b=NULL)
foo

is.null(foo[["a"]]) # FALSE
is.null(foo[["b"]]) # TRUE, but the element "exists"...
is.null(foo[["c"]]) # TRUE

"a" %in% names(foo) # TRUE
"b" %in% names(foo) # TRUE
"c" %in% names(foo) # FALSE

...and foo[["a"]] is safer than foo$a, since the latter uses partial matching and thus might also match a longer name:

x <- list(abc=4)
x$a  # 4, since it partially matches abc
x[["a"]] # NULL, no match

[UPDATE] So, back to the question why exists('foo$a') doesn't work. The exists function only checks if a variable exists in an environment, not if parts of a object exist. The string "foo$a" is interpreted literary: Is there a variable called "foo$a"? ...and the answer is FALSE...

foo <- list(a=42, b=NULL) # variable "foo" with element "a"
"bar$a" <- 42   # A variable actually called "bar$a"...
ls() # will include "foo" and "bar$a" 
exists("foo$a") # FALSE 
exists("bar$a") # TRUE

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...