В R пишите функции на лету (для контента sparkTable)

Я учусь использовать пакет sparkTable. Я создаю таблицы, имеющие sparkLine, за которыми следует определенное количество столбцов (не фиксировано). Все столбцы достигают одной и той же цели: отображают n-й элемент временного ряда, округленный до 2 цифр. Например, столбец 1, следующий за искровым графиком, будет отображать значение 1-й временной точки, 2-го столбца, 2-й точки данных и т. д. На данный момент я справляюсь с этим:

Сначала объявить список функций, учитывающих столько моментов времени, сколько я могу ожидать в данных.

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))

Затем при вызове newSparkTable я делаю аргумент tableContent «расширенным» до количества моментов времени, присутствующих в данных:

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

Это работает хорошо, но я думаю, что должен быть более гибкий подход (я думаю о лямбда-функциях в Python или что-то в этом роде). Идеи приветствуются.

Изменить

Я приближаюсь к этому. Способ оценки этого кода поможет:

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)"

Но потом:

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

Оценивается только последний. :с


person Dominic Comtois    schedule 09.11.2014    source источник
comment
Создание анонимной функции с function в R эквивалентно lambda в Python. Какой гибкости вы пытаетесь достичь? Вы можете создать эти анонимные функции внутри цикла или функции применения.   -  person Nick Ulle    schedule 09.11.2014
comment
Я добавил краткий пример того, чего я пытаюсь достичь.   -  person Dominic Comtois    schedule 09.11.2014
comment
Создание функции в виде строки и ее вычисление не очень похоже на R. Чего вы пытаетесь достичь? Возможно, мы сможем пролить свет с другой точки зрения, если будем знать, какова конечная цель.   -  person Roman Luštrik    schedule 09.11.2014
comment
В самой базовой форме я пытаюсь научиться лучше делать то, что я делал. Например, если количество столбцов подскочит до 30, было бы нелепо писать еще 20 функций в мой список get.value на случай, если он станет таким большим... и что потом? 120? Кто знает. Поэтому я был бы рад создать такой список на лету на основе заданного числа, будь то 3 или 38, а затем передать этот список функции newSpartTable(). У меня может быть лицо, чтобы закрыть проблему прямо сейчас, но я не вижу решения.   -  person Dominic Comtois    schedule 09.11.2014


Ответы (1)


Используйте lapply с фабричной функцией, чтобы создать список функций:

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

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

Промежуточная переменная j необходима для привязки значения index к локальной области видимости.

person Nick Ulle    schedule 09.11.2014
comment
вместо этого вы можете использовать force(index) - person baptiste; 09.11.2014
comment
Спасибо, Ник и Батист, вы помогли мне узнать здесь что-то новое! - person Dominic Comtois; 13.11.2014