Skip to content

programming questions

11 messages · Duncan Murdoch, Jonathan P Daily, Barry Rowlingson +4 more

#
quick programming questions.  I want to "turn on" more errors.  there
are two traps I occasionally fall into.

* I wonder why R thinks that a variable is always defined in a data frame.

     > is.defined(d)
     [1] FALSE
     > d= data.frame( x=1:5, y=1:5 )
     > is.defined(d$z)
     [1] TRUE
     > is.defined(nonexisting$garbage)
     [1] TRUE

this is a bit unfortunate for me, because subsequent errors become
less clear.   right now, I need to do '(is.defined(d) and
!is.null(d$z))' to check that my function inputs are valid.  It would
be nicer if one could just write "if (is.defined(d$z)".

* is there a way to turn off automatic recycling?  I would rather get
an error than unexpected recycling.  I can force recycling with rep()
when I need to.

regards,

/iaw

----
Ivo Welch (ivo.welch at brown.edu, ivo.welch at gmail.com)
#
ivo welch wrote:
Which package/version of R is the 'is.defined' function in?

I don't seem to have it here on 2.11.1, which I know is not
the latest version of R.

What does 'defined' mean?
"z" %in% names(d) ?
#
On 03/11/2010 2:05 PM, ivo welch wrote:
Where did you find the is.defined() function?  It's not part of R.  The 
R function to do that is exists().

Duncan Murdoch
#
yikes.  this is all my fault.  it was the first thing that I ever
defined when I started using R.

   is.defined <- function(name) exists(as.character(substitute(name)))

I presume there is something much better...

/iaw
On Wed, Nov 3, 2010 at 2:12 PM, Erik Iverson <eriki at ccbr.umn.edu> wrote:
#
On Wed, Nov 3, 2010 at 6:17 PM, ivo welch <ivo.welch at gmail.com> wrote:
You didn't do a good job testing your is.defined :)

 Let's see what happens when you feed it 'nonexisting$garbage'. What
gets passed into 'exists'?

acs=function(name){as.character(substitute(name))}

 > acs(nonexisting$garbage)
[1] "$"           "nonexisting" "garbage"

 - and then your exists test is doing effectively exists("$") which
exists. Hence TRUE.

 What you are getting here is the expression parsed up as a function
call ($) and its args. You'll see this if you do:

 > acs(fix(me))
[1] "fix" "me"

Perhaps you meant to deparse it:

 > acs=function(name){as.character(deparse(substitute(name)))}
 > acs(nonexisting$garbage)
 [1] "nonexisting$garbage"
 > exists(acs(nonexisting$garbage))
 [1] FALSE

But you'd be better off testing list elements with is.null

Barry
#
thanks, barry and eric.  I didn't do a good job---I did an awful job.

alas, should R not come with an is.defined() function?  a variable may
never have been created, and this is different from a variable
existing but holding a NULL.  this can be the case in the global
environment or in a data frame.

  > is.null(never.before.seen)
  Error: objected 'never.before.seen' not found
  > is.defined(never.before.seen)  ## I need this, because I do not
want an error:
  [1] FALSE

your acs function doesn't really do what I want, either, because {
d=data.frame( x=1:4); exists(acs(d$x)) } tells me FALSE .  I really
need

  > d <- data.frame( x=1:5, y=1:5 )
  > is.defined(d$x)
  TRUE
  > is.defined(d$z)
  FALSE
  > is.defined(never.before.seen)
  FALSE
  > is.defined(never.before.seen$anything)  ## if a list does not
exist, anything in it does not exist either
  FALSE

how would I define this function?

regards,

/iaw

On Wed, Nov 3, 2010 at 2:48 PM, Barry Rowlingson
<b.rowlingson at lancaster.ac.uk> wrote:
#
?exists

a variable may
exists("never.before.seen") #notice the quotes
[1] FALSE
with(d, exists("x"))
with(d, exists("z"))
exists("never.before.seen")
This one I'm a bit confused about.  If you're
programming a function, then the user either:

1) passes in an object, which is bound to a
local variable, and therefore exists. You can
do checks on that object to see that it conforms
to any constraints you have set.

2) does not pass in the object, in which case
you can test for that with ?missing.

Is writing your own functions for others to
use what you're doing?

--Erik
#
On Nov 3, 2010, at 3:32 PM, ivo welch wrote:

            
Except the $ function return NULL rather than an error and you already  
said you were willing to accept a NULL value as being different than  
not-existing.

You may want to look at the difference between `$` and `[` methods of  
accessing values.

You can test for never.before.seen as an object

is.defined <- function(x) !("try-error" %in% class(try(x)) )

But it won't give your desired result on d$never.before.seen which  
does not throw an error. For that you would need an additional test of  
the sort Iverson is suggesting.
#
thanks, eric---I need a little more clarification.  *yes, I write
functions and then forget them.  so I want them to be self-sufficient.
 I want to write functions that check all their arguments for
validity.)  For example,

  my.fn <- function( mylist ) {
      stop.if.not( is.defined(mylist) )  ## ok, superfluous
      stop.if.not( is.defined(mylist$dataframe.in.mylist ))
      stop.if.not( is.defined(mylist$dataframe.in.mylist$a.component.I.need) )
      ### other checks, such as whether the component I need is long
enough, positive, etc.
      ### could be various other operations
      mylist$dataframe.in.mylist$a.component.I.need
  }

so

  my.fn( asd )   ## R gives me an error, asd is not in existence
  my.fn( NULL )  ## second error: the list component
'dataframe.in.mylist' I need is not there
  my.fn( data.frame( some.other.component=1:4 ) )  ## second error;
the list component  'dataframe.in.mylist' I need is not there
  my.fn( list( hello=1, silly=data.frame( x=1:4 ) ) ) ## second error:
dataframe.in.mylist does not exist
  my.fn( list( hello=2, dataframe.in.mylist= data.frame(
a.component.I.need=1:4 ))  ## ok

exists() works on a "stringified" variable name.  how do I stringify in R?


PS: btw, is it possible to weave documentation into my user function,
so that I can type "?is.defined" and I get a doc page that I have
written?  Ala perl pod.  I think I asked this before, and the answer
was no.

/iaw



----
Ivo Welch (ivo.welch at brown.edu, ivo.welch at gmail.com)
CV Starr Professor of Economics (Finance), Brown University
http://www.ivo-welch.info/
On Wed, Nov 3, 2010 at 3:40 PM, Erik Iverson <eriki at ccbr.umn.edu> wrote:
#
On Wed, Nov 3, 2010 at 1:04 PM, ivo welch <ivo.welch at gmail.com> wrote:
See the Arguments class in R.utils, e.g.

library("R.utils");

my.fn <- function(mylist) {
  # Assert a data.frame element exists
  df <- Arguments$getInstanceOf(mylist$dataframe.in.mylist, "data.frame");

  # Assert x >= 0 and of length 45:67.
  x <- df$a.component.I.need;
  x <- Arguments$getDoubles(x, range=c(0,Inf), length=c(45,67));

? ?### could be various other operations
? ?mylist$dataframe.in.mylist$a.component.I.need
}

/Henrik