2

Sorry if this is a duplicate. I am very new to data.table. Basically, I am able to get my code to work outside of functions, but when I pack the operations inside of a function, they breakdown. Ultimately, I had hoped to make the functions age.inds and m.inds internal functions in a package.

# required functions ------------------------------------------------------

# create object
create.obj <- function(n = 100){
  obj = list()
  obj$inds <- data.table(age = rep(0.1, n), m = NA)
  obj$m$model <- function(age, a){return(age^a)}
  obj$m$params <- list(a = 2)
  return(obj)
}

# calculate new 'age' of inds
age.inds <- function(obj){
  obj$inds[, age := age + 1]
  return(obj)
}

# calculate new 'm' of inds
m.inds <- function(obj){
  ARGS <- list()
  args.incl <- which(names(obj$m$params) %in% names(formals(obj$m$model)))
  ARGS <- c(ARGS, obj$m$params[args.incl])
  args.incl <- names(obj$inds)[names(obj$inds) %in% names(formals(obj$m$model))]
  ARGS <- c(ARGS, obj$inds[, ..args.incl]) # double dot '..' version
  # ARGS <- c(ARGS, inds[, args.incl, with = FALSE]) # 'with' version

  obj$inds[, m := do.call(obj$m$model, ARGS)]
  return(obj)
}

# advance object
adv.obj <- function(obj, times = 1){
  for(i in seq(times)){
    obj <- age.inds(obj)
    obj <- m.inds(obj)
  }
  return(obj)
}



# Example  ----------------------------------------------------------------
# this doesn't work
obj <- create.obj(n = 10)
obj # so far so good
obj <- age.inds(obj)
obj # 'inds' gone

# would ultimately like to call adv.obj
obj <- adv.obj(obj, times = 5)

Also (as a side note), most of what I would like to do in my code would be vectorized calculations (i.e. updating variables in obj$inds), so I don't even know if going to data.tables makes too much sense for me (i.e. no by grouping operations as of yet). I am dealing with large objects and wondered if switching from data.frame objects would speed things up (I can get my code to work using data.frames).

Thanks

Update

OK, the issue with the printing has been solved thanks to @eddi. I am however unable to use these "inds" functions when they are located internally within a package (i.e not exported). I made a small package (DTtester), that has this example in the help file for adv.obj:

obj <- create.obj(n=10)
obj <- adv.obj(obj, times = 5)
# Error in `:=`(age, new.age) : 
# Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are 
# defined for use in j, once only and in particular ways. See help(":=").

Any idea why the functions would fail in this way?

Community
  • 1
  • 1
Marc in the box
  • 11,769
  • 4
  • 47
  • 97
  • 2
    to clarify a little on the duplicate - it's still there and will get printed next time you type `obj` or `print` it – eddi Oct 04 '18 at 14:25
  • @eddi - thank you. This is very helpful. If you are able to comment on my adapted question, I would be most grateful. – Marc in the box Oct 04 '18 at 15:33
  • I don't get any errors. Try in a clean session and/or update your `data.table` version. – eddi Oct 04 '18 at 16:10
  • @eddi - Hmm... No, it still doesn't work for me. I have updated all packages and reinstalled with dependencies (I'm using 64Bit R 3.5.1). – Marc in the box Oct 04 '18 at 17:20
  • You're not running the same code as above, as evidenced by the error (which says you're doing `age := new.age` somewhere on a `data.frame`), so I'm not sure how to help you. – eddi Oct 04 '18 at 18:59
  • Sorry, I made an attempt to adjust that function in the package. I returned it to the same as above and still get the error. Did you try running my package? The error only occurs when the function is an internal. – Marc in the box Oct 05 '18 at 03:47
  • sounds like this is your issue: `https://github.com/Rdatatable/data.table/issues/2341` – eddi Oct 05 '18 at 14:36

0 Answers0