0

I'm learning to use the sparkTable package. I'm creating tables having a sparkLine followed by a certain numbers of columns (not fixed). The columns all achieve the same thing: display the n'th element of the time series, rounded to 2 digits. For instance, column 1 following the spark graph will display the value of the 1st time point, 2nd column, the 2nd data point, and so on. For now, I deal with it by:

First declaring a list of functions allowing for as many time points I might expect to come up in the data.

get.values <- list(function(x) round(x[1],2),
                   function(x) round(x[2],2),
                   function(x) round(x[3],2),
                   function(x) round(x[4],2),
                   function(x) round(x[5],2),
                   function(x) round(x[6],2),
                   function(x) round(x[7],2),
                   function(x) round(x[8],2),
                   function(x) round(x[9],2),
                   function(x) round(x[10],2))

Then, when calling newSparkTable, I make the tableContent argument "expand" to the number of time points present in the data:

st <- newSparkTable(my.data, tableContent = c(list(newSparkLine()), 
                                              get.values[1:max(my.data$time)]),
                    ...)

This works well, but I'm thinking there must be a more flexible approach (I'm thinking of lambda functions in Python, or something like that). Ideas most welcome.

Edit

I'm getting closer to it. A way to have this code evaluated would do the trick:

paste("function(x) round(x[", 1:max(my.data$time), "],2)", sep="")

# For instance if max(my.data$time)==10
> paste("function(x) round(x[", 1:10, "],2)", sep="")
 [1] "function(x) round(x[1],2)"  "function(x) round(x[2],2)"  "function(x) round(x[3],2)" 
 [4] "function(x) round(x[4],2)"  "function(x) round(x[5],2)"  "function(x) round(x[6],2)" 
 [7] "function(x) round(x[7],2)"  "function(x) round(x[8],2)"  "function(x) round(x[9],2)" 
[10] "function(x) round(x[10],2)"

But then:

> eval(parse(text=paste("function(x) round(x[", 1:10, "],2)", sep="")))
function(x) round(x[10],2)

Only the last one gets eval'd. :s

Dominic Comtois
  • 10,230
  • 1
  • 39
  • 61
  • Creating an anonymous function with `function` in R is equivalent to a `lambda` in Python. What kind of flexibility are you trying to achieve? You could create these anonymous functions within a loop or an apply function. – Nick Ulle Nov 09 '14 at 06:41
  • I added a short example of where I'm trying to getting at. – Dominic Comtois Nov 09 '14 at 07:03
  • Creating a function as a string and evaluating it doesn't seem very R-like. What are you trying to achieve? Perhaps we can shed some light from a different perspective if we know what the end goal is. – Roman Luštrik Nov 09 '14 at 08:10
  • At it's most basic form, I'm trying to learn a better way to do what I did. For instance, if the number of columns were to jump to 30, it would seem ridiculous to write 20 more functions into my `get.value` list "just in case in goes that high"... and then what? 120? Who knows. So I'd be happy generating on-the-fly such a list based on a given number, be it 3, or 38, and then feeding that list to the `newSpartTable()`function. I might have the face to close to the problem right now but I can't see the solution. – Dominic Comtois Nov 09 '14 at 08:36

1 Answers1

1

Use lapply with a factory function to create the list of functions:

round.factory = function(index) {
    j = index
    function(x) round(x[j], 2)
}

get.values = lapply(1:10, round.factory)

The intermediate variable j is necessary to to bind the value of index to the local scope.

Nick Ulle
  • 409
  • 5
  • 14