#r #matrix #rcpp
#r #матрица #rcpp
Вопрос:
Я разрабатывал пакет R для анализа РНК-последовательности отдельных клеток, и одна из функций, которые я неоднократно использовал, вычисляет матрицу косинусного различия для заданной матрицы из m клеток по n генам. Функция, которую я написал, заключается в следующем:
CosineDist <- function(input = NULL) {
if (is.null(input)) { stop("You forgot to provide an input matrix") }
dist_mat <- as.dist(1 - input %*% t(input) / (sqrt(rowSums(input^2) %*% t(rowSums(input^2)))))
return(dist_mat)
}
Этот код отлично работает для небольших наборов данных, но когда я запускаю его для чего-либо более 20 000 строк, это занимает целую вечность, а затем завершает работу моего сеанса R из-за проблем с памятью. Я считаю, что перенос этого в Rcpp сделал бы это быстрее и эффективнее с точки зрения памяти (я знаю, что это немного наивное убеждение, но мои знания C в целом ограничены). Наконец, выходные данные функции, хотя при возврате они не обязательно должны быть объектом матрицы расстояний, должны иметь возможность преобразования в этот формат после его генерации.
Как мне следует преобразовать эту функцию в Rcpp, а затем вызвать ее так же, как и любую другую функцию в моем пакете? В качестве альтернативы, это лучший способ решить проблему скорости / памяти?
Комментарии:
1. Как это соотносится с существующей функцией
cosine()
в пакетеisa
?2. Это должна быть простая функция в Rcpp, но ваш вопрос, по сути, «может ли кто-нибудь показать мне, как работает Rcpp, и преобразовать мою функцию в C ?». Это действительно выходит за рамки того, что возможно или по теме о переполнении стека. Гораздо лучше прочитать хороший бесплатный вводный текст Rcpp , который включает в себя главу о матрицах
3. Я не знал об этом пакете или функции, я попробую прямо сейчас.
4. из проверки исходного кода функция косинуса из isa также является чистой реализацией R
5. Кажется, я не могу найти этот
isa
пакет, хотя естьisa2
пакет, в котором нет функции косинусного расстояния.
Ответ №1:
Трудно вам помочь, поскольку, как указано в комментариях, вы в основном ищете вводную часть Rcpp.
Я попытаюсь дать вам несколько советов, о которых я уже частично упоминал в комментариях.
В целом использование C / C может обеспечить значительное ускорение (в зависимости от задачи, конечно). Но я достиг (интенсивный цикл, не оптимизированный код) 100-кратного ускорения.
Поскольку добавление C может быть сложным и иногда вызывать проблемы, прежде чем идти этим путем, проверьте следующее:
1. Оптимизирован ли ваш R-код?
Здесь вы можете сделать много неправильных решений (например, циклы в R медленные). Часто можно легко достичь ускорения кода R в 10 раз или намного больше, просто оптимизируя его.
2. Есть ли лучшие реализации в других пакетах?
Особенно, если это вспомогательные функции или общие функциональные возможности, часто они уже реализованы в других пакетах. Проведите сравнительный анализ различных существующих решений с помощью пакета «microbenchmark». Проще просто использовать оптимизированную функцию из другого пакета R, а затем делать все самостоятельно. (возможно, другие реализации пакета уже есть на C ). В основном я пытаюсь искать основные и популярные пакеты (поскольку они лучше протестированы и вряд ли внезапно выпадут из CRAN).
3. Профилируйте свой код
Посмотрите, какие части точно вызывают проблемы со скоростью / памятью. Возможно, вы можете сохранить части в R и создать функцию только для критических частей в C . Или вы найдете другой пакет, в котором есть функция R, реализованная на C именно для этой важной части.
В конце я бы сказал, что я предпочитаю использовать Rcpp / C вместо кода на C. Думаю, это самый простой способ. Для части обучения Rcpp вам нужно перейти к специальному руководству (а не к вопросу SO).
Комментарии:
1. Спасибо, я ценю все усилия, которые вы приложили, чтобы помочь мне в этом.