#r #optimization #dplyr
#r #оптимизация #dplyr
Вопрос:
У меня есть 2 вектора одинаковой длины x,y
. Тогда x^2,y^2
являются квадратными (поэлементно) x,y
соответственно. На каждой итерации мне нужно применить функцию cummean
on x,y,x^2,y^2
.
Я хотел бы спросить, могу ли я каким-то образом ускорить процесс, а не выполнять 4 отдельные операции.
library(dplyr)
x <- c(1, 2, 3)
y <- c(5, 5, 6)
dplyr::cummean(x)
dplyr::cummean(y)
dplyr::cummean(x^2)
dplyr::cummean(y^2)
Большое спасибо за ваше предложение!
Комментарии:
1. Я не думаю, что имеется достаточно общей информации, чтобы предложить ускорение. Это зависит от того, как вы используете их в своем коде. Это 4 независимые операции. Вы могли бы сократить строку кода, используя
lapply
i.elapply(list(x, y), function(x) list(cummean(x), cummean(x^2)))
, но это не дает увеличения скорости.2. Я тестировал в Rcpp, но dplyr ::cummean уже работает очень быстро, поэтому никаких улучшений. Обязательно обновитесь до версии dplyr v1.0.2, потому что в dplyr v1.0.0 была ошибка с cummean
Ответ №1:
Я думаю, вы могли бы сделать что-то вроде:
tibble(x, y) %>%
mutate(across(1:2, ~.x^2, .names = c("{col}^2"))) %>%
mutate(across(1:4, cummean, .names = "cummean_{col}"))
#> # A tibble: 3 x 8
#> x y `x^2` `y^2` cummean_x cummean_y `cummean_x^2` `cummean_y^2`
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 1 5 1 25 1 5 1 25
#> 2 2 5 4 25 1 5 1 25
#> 3 3 6 9 36 1.33 5 2 25
И если вы хотите, чтобы переменные находились в глобальной среде, а не в tibble, вы могли бы сделать:
tibble(x, y) %>%
mutate(across(1:2, ~.x^2, .names = c("{col}^2"))) %>%
mutate(across(1:4, cummean, .names = "cummean_{col}")) %>%
as.list() %>%
list2env(envir = globalenv())
Или в функции, если вам приходилось часто это делать, вы могли бы сделать:
func <- function(x, y)
{
tibble(x, y) %>%
mutate(across(1:2, ~.x^2, .names = c("{col}^2"))) %>%
mutate(across(1:4, cummean, .names = "cummean_{col}")) %>%
as.list() %>%
list2env(envir = parent.frame())
}
Комментарии:
1. к сожалению
microbenchmark
, по сравнению с 4 отдельными операциями чрезвычайно медленно2. @Waldi Я предположил, что OP означает «избегать повторения кодирования», а не «улучшать скорость обработки», поскольку они сказали «вместо выполнения 4 отдельных операций». Однако я могу ошибаться в этом. Что касается скорости обработки raw, я предполагаю, что вы не сможете значительно улучшить
cummean
— вот почему еще одна причина, по которой я предполагаю, что OP искал код, который предотвращал повторение, а не ускорение. Разъяснение помогло бы. Спасибо за тестирование @Waldi3. спасибо за ваш отзыв: давайте дождемся разъяснений от OP о том, как понять вопрос! И вы правы,
cummean
кажется непревзойденным по скорости.4. Я имел в виду код для увеличения скорости моего алгоритма. Таким образом, @Waldi прав.