Контрольный анализ и отображение результатов анализа И контрольного показателя?

Вероятно, я просто пропустил параметр ... но, может быть, кто-нибудь может указать мне на него: как можно запустить анализ в R, протестировать его и все же где-то сохранить результат ?. Я знаю, что функции R могут возвращать только один единственный объект, но я мог бы либо использовать список здесь, либо вставить результаты теста и сохранить анализ в возвращаемом значении функции.

Но есть ли способ оценить эталонный тест (или system.time) и анализ, не выполняя его дважды, как это ?:

require(rbenchmark)
bmark <- function(x){
    res <- list()
    res[[1]] <- benchmark(x^6)
    res[[2]] <- x^6
    res
}

РЕДАКТИРОВАТЬ: Мне очень жаль, что я вызвал некоторую путаницу в том, что я действительно хочу делать. Возможно, вариант использования проясняет ситуацию: у меня нет типичной тестовой ситуации, когда я хочу проверить, работает ли моя пользовательская функция быстрее, чем какая-либо другая функция. Скорее, я запускаю одно и то же с разными данными на разных машинах. Мне это не нужно в тестовой среде, но на производстве - я просто хочу, чтобы пользователи сценария знали, сколько времени это заняло. Если это час или больше, люди могут спланировать свой обеденный перерыв :).


person Matt Bannert    schedule 18.02.2013    source источник


Ответы (3)


Вот пример использования двух функций. Первый использует plyr, а второй - data.table.

# dummy data
require(plyr)
require(data.table)
set.seed(45)
x1 <- data.frame(x=rnorm(1e6), grp = sample(letters[1:26], 1e6, replace=T))
x1.dt <- data.table(x1, key="grp")
# function that uses plyr   
DF.FUN <- function(x) {
    ddply(x1, .(grp), summarise, m.x = mean(x))
}

# function that uses data.table
DT.FUN <- function(x) {
    x1.dt[, list(m.x=mean(x)),by=grp]
}

require(rbenchmark)
> benchmark( s1 <- DF.FUN(), s2 <- DT.FUN(), order="elapsed", replications=2)

#             test replications elapsed relative user.self sys.self user.child sys.child
# 2 s2 <- DT.FUN()            2   0.036    1.000     0.031    0.006          0         0
# 1 s1 <- DF.FUN()            2   0.527   14.639     0.363    0.163          0         0

Теперь s1 и s2 содержат результаты каждой функции, и результаты тестирования будут отображаться на экране.

# > head(s1)
#   grp           m.x
# 1   a  0.0069312201
# 2   b -0.0002422315
# 3   c -0.0129449586
# 4   d -0.0036275338
# 5   e  0.0013438022
# 6   f -0.0015428427

# > head(s2)
#    grp           m.x
# 1:   a  0.0069312201
# 2:   b -0.0002422315
# 3:   c -0.0129449586
# 4:   d -0.0036275338
# 5:   e  0.0013438022
# 6:   f -0.0015428427

Это то, что вам было нужно?

person Arun    schedule 18.02.2013
comment
Тестирую и data.table в 20 раз быстрее :) +1 даже если нам нужно установить 2 пакета :) - person agstudy; 18.02.2013

Я читаю вопрос немного иначе, чем Арун. Это был бы ответ на то, что, как я думал, меня спрашивают:

 > bres <- bmark(2)
> bres
[[1]]
  test replications elapsed relative user.self sys.self user.child sys.child
1  x^6          100   0.001        1     0.001    0.001          0         0

[[2]]
[1] 64

Функция bmark возвращает результат с 100 повторениями по умолчанию. Если вы хотите аннотировать результаты, вы можете использовать paste (), и если вы хотите добавить параметр для количества повторений:

bmark2 <- function(x, reps=100){
    res <- list()
    res[[1]] <- benchmark(x^6, replications=reps)
    res[[2]] <- paste(reps, " replications of ", x, "to the 6th in", res[[1]]$elapsed)
    res
}
person IRTFM    schedule 18.02.2013
comment
Спасибо за ваш ответ +1, действительно, это очень близко и помогает, просто мне здесь не нужны реплики. Отредактировал свой вопрос, чтобы (надеюсь) прояснить ситуацию. - person Matt Bannert; 19.02.2013

Я не уверен, что думает StackOverflow об ответах на старые вопросы, но похоже, что после вашего редактирования никто не ответил. Итак, вот оно:

Чтобы рассчитать время процесса в R, вы можете использовать два метода. Первый использует system.time(expression) и показывает, сколько времени потребовалось для вычисления выражения в скобках. Если в вашем случае это нецелесообразно, вы можете получить системное время с помощью Sys.time() до операции и после операции и вычесть два.

Если это наконец ответ на ваш вопрос, примите решение :)

person Gullydwarf    schedule 17.11.2014