#r #loops #break #next #microbenchmark
Вопрос:
Я знаю, что это, вероятно, простой вопрос, но я изо всех сил стараюсь учиться и совершенствоваться. Когда я пробую этот код, он выдает мне ошибку: «нет цикла для разрыва/следующего, перехода на верхний уровень». Может ли кто-нибудь подсказать, почему и помочь мне? Большое вам спасибо.
x_1 <- rnorm(100)
x_2 <- rnorm(10000)
x_3 <- rnorm(1000000)
to_evaluate <- list(x_1, x_2, x_3)
speed_test <- for (i in to_evaluate) {
microbenchmark(mean_loop(i), mean_mat(i), mean(i))
}
print(speed_test)
Код для mean_loop и mean_mat:
x <- c(1:11)
mean_loop <- function(x) {
sum_of_x <- 0
for(i in x){
sum_of_x <- sum_of_x x[i]
}
mean_of_x <- sum_of_x/length(x)
return(mean_of_x)
}
mean_mat <- function(x) {
sum(diag(length(x))%*%x)/length(x)
}
Функция microbenchmark
(из пакета microbenchmark
) позволяет измерить скорость выполнения кода. Если вы дадите ему код для оценки, он оценит его 100 раз и вернет сводную статистику о том, сколько времени потребовалось для запуска кода. Если вы дадите ему несколько выражений, он будет делать это для каждого выражения.
Комментарии:
1. Может быть, попробуем использовать
for (i in length(to_evaluate)
. Кроме того, рассматривали ли вы возможность использованияlapply
? т. е.lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))
? Не могли бы вы добавить пакеты , которые вы используете для функцийmicrobenchmark()
mean_loop()
иmean_mat()
?2. Спасибо! Я добавил код. к сожалению, ни одно из ваших решений не сработало для меня, но спасибо вам за попытку помочь!
Ответ №1:
Это работает для меня, используя определения функций из вопроса —
x_1 <- rnorm(10)
x_2 <- rnorm(100)
x_3 <- rnorm(1000)
library(microbenchmark)
to_evaluate <- list(x_1, x_2, x_3)
result <- vector('list', length(to_evaluate))
for (i in seq_along(to_evaluate)) {
val <- to_evaluate[[i]]
result[[i]] <- microbenchmark(mean_loop(val), mean_mat(val), mean(val))
}
result
#[[1]]
#Unit: microseconds
# expr min lq mean median uq max neval cld
# mean_loop(val) 2.818 3.2495 7.62632 4.204 5.847 41.214 100 a
# mean_mat(val) 2.547 2.9765 7.90376 3.571 4.940 93.155 100 a
# mean(val) 1.896 2.1700 6.59605 2.818 4.204 116.467 100 a
#[[2]]
#Unit: microseconds
# expr min lq mean median uq max neval cld
#mean_loop(val) 49.368 89.8705 92.81099 92.820 99.6505 179.400 100 c
# mean_mat(val) 18.968 50.7335 55.61163 52.987 55.5770 141.363 100 b
# mean(val) 2.090 2.2815 3.87982 2.803 3.3115 33.779 100 a
#[[3]]
#Unit: microseconds
# expr min lq mean median uq max neval cld
# mean_loop(val) 1359.527 1511.9295 3312.36578 1835.326 2970.1350 16455.048 100 b
# mean_mat(val) 1713.178 2155.3815 4032.53143 2352.858 2739.6650 19783.264 100 b
# mean(val) 3.708 4.6695 16.39451 14.881 21.8355 162.184 100 a
Ответ №2:
Используя lapply()
вы могли бы сделать:
speed_test <- lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))
print(speed_test)
Пример:
# had to remove x_3 to overcome a crash not linked with the use of a loop or lapply, see the Note at the end of the post
x_1 <- rnorm(100)
x_2 <- rnorm(10000)
to_evaluate <- list(x_1, x_2)
library(microbenchmark)
speed_test <- lapply(to_evaluate, function(x) microbenchmark(mean_loop(x), mean_mat(x), mean(x)))
Выход:
> print(speed_test)
[[1]]
Unit: microseconds
expr min lq mean median uq max neval cld
mean_loop(x) 35.3 36.05 67.174 36.85 37.3 3000.9 100 a
mean_mat(x) 19.7 20.25 38.090 20.60 20.9 1761.0 100 a
mean(x) 2.0 2.30 2.793 2.70 2.9 13.8 100 a
[[2]]
Unit: microseconds
expr min lq mean median uq max neval cld
mean_loop(x) 126214.8 139520.40 211537.906 182460.50 245618.95 463139.9 100 b
mean_mat(x) 275451.1 314082.60 337446.084 340836.75 358470.35 411152.0 100 c
mean(x) 16.7 20.15 31.192 33.35 35.35 82.0 100 a
Примечание:
Независимо от того, использую ли я loop of lapply на своем компьютере, я сталкиваюсь с проблемой производительности, не связанной с вашим вопросом. Т. е. даже это не работает для меня microbenchmark(mean_loop(to_evaluate[[3]]), mean_mat(to_evaluate[[3]]), mean(to_evaluate[[3]]))
, в то время как другие работают нормально (с to_evaluate[[1]]
и to_evaluate[[2]]
).
Комментарии:
1. Привет, Пол! Спасибо! Я пытался, но ошибка «нет цикла для разрыва/следующего, переход на верхний уровень» продолжает появляться. Я думаю, что ошибка на самом деле находится внутри microbenchmark().
2. @CeciliaBonucchi Код, представленный в этом ответе, работает для меня и выдает показанный результат :/ Однако по некоторым причинам, если я включу пользовательские функции
mean_mat()
, иmean_loop()
он выйдет из строя, но по другой причине, чем та, на которую вы указываете3. Я только что проверил и получил те же самые рассуждения. Я думаю, что microbenchmark не может выполнять несколько функций одновременно. Как вы думаете, мне нужна вложенная петля или вложенный цикл? Не могли бы вы попытаться помочь мне его построить? Огромное спасибо
4. @CeciliaBonucchi, Ронак решил вашу проблему с циклом, я думаю, поэтому я сосредоточил свой ответ на идее,
lapply
однако я не могу проверить ее из-за другой проблемы, которая не связана с вашим вопросом. Мне кажетсяmicrobenchmark()
, что я действительно могу обрабатывать несколько функций одновременно.5. Большое вам спасибо за все усилия, которые вы приложили, чтобы помочь мне! Я постараюсь, чтобы ваш код (который действительно интересен) работал и для x_3! Еще раз спасибо!!