Я хочу посмотреть на исходный код функции, чтобы увидеть, как она работает. Я знаю, что могу напечатать функцию, введя ее имя в командной строке:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
В этом случае, что это UseMethod("t")
значит? Как мне найти исходный код, который фактически используется, например:t(1:10)
:?
Есть ли разница между тем, когда я вижу, UseMethod
и когда я вижу, standardGeneric
и showMethods
, как с with
?
> with
standardGeneric for "with" defined from package "base"
function (data, expr, ...)
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use showMethods("with") for currently available ones.
В других случаях я вижу, что вызываются функции R, но я не могу найти исходный код для этих функций.
> ts.union
function (..., dframe = FALSE)
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found
Как мне найти такие функции, как .cbindts
и.makeNamesTs
?
В других случаях есть немного кода R, но большая часть работы, похоже, выполняется где-то еще.
> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
{
if (is.object(data) || !is.atomic(data))
data <- as.vector(data)
.Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow),
missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call) .Primitive(".Internal")
> .Primitive
function (name) .Primitive(".Primitive")
Как мне узнать, что .Primitive
делает функция? Кроме того , некоторые функции называют .C
, .Call
, .Fortran
, .External
, или .Internal
. Как я могу найти исходный код для тех?
Ответы:
UseMethod("t")
говорит вам, чтоt()
это ( S3 ) универсальная функция, которая имеет методы для различных классов объектов.Система диспетчеризации метода S3
Для классов S3 вы можете использовать
methods
функцию для перечисления методов для определенной универсальной функции или класса.«Невидимые функции отмечены звездочкой» означает, что функция не экспортируется из пространства имен своего пакета. Вы по-прежнему можете просматривать его исходный код с помощью
:::
функции (то естьstats:::t.ts
) или с помощьюgetAnywhere()
.getAnywhere()
полезно, потому что вам не нужно знать, из какого пакета пришла функция.Система диспетчеризации метода S4
Система S4 является более новой системой диспетчеризации методов и является альтернативой системе S3. Вот пример функции S4:
Вывод уже предлагает много информации.
standardGeneric
является индикатором функции S4. Метод, чтобы увидеть определенные методы S4 предлагается услужливо:getMethod
может быть использован для просмотра исходного кода одного из методов:Есть также методы с более сложными сигнатурами для каждого метода, например
Чтобы увидеть исходный код для одного из этих методов, должна быть указана вся подпись, например
Недостаточно предоставить частичную подпись
Функции, которые вызывают неэкспортированные функции
В случае
ts.union
,.cbindts
и.makeNamesTs
неэкспортируемые функции изstats
пространства имен. Вы можете просмотреть исходный код неэкспортируемых функций с помощью:::
оператора илиgetAnywhere
.Функции, которые вызывают скомпилированный код
Обратите внимание, что «скомпилированный» не ссылается на байтово-скомпилированный R-код, созданный пакетом компилятора .
<bytecode: 0x294e410>
Строка в выводе выше показывает , что функция байт скомпилированные, и вы все еще можете просмотреть исходный код из командной строки R.Функции, вызов
.C
,.Call
,.Fortran
,.External
,.Internal
, или.Primitive
вызывают точки входа в скомпилированном коде, так что вы должны смотреть на источниках скомпилированного кода , если вы хотите , чтобы полностью понять функцию. Это зеркало GitHub исходного кода R - хорошее место для начала. Эта функцияpryr::show_c_source
может быть полезным инструментом, поскольку она приведет вас прямо на страницу GitHub.Internal
и.Primitive
вызовы. Пакеты могут использовать.C
,.Call
,.Fortran
и.External
; но не.Internal
или.Primitive
, потому что они используются для вызова функций, встроенных в интерпретатор R.При вызовах некоторых из вышеуказанных функций может использоваться объект вместо символьной строки для ссылки на скомпилированную функцию. В этих случаях объект класса
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
или"NativeSymbol"
; и печать объекта дает полезную информацию. Например,optim
звонки.External2(C_optimhess, res$par, fn1, gr1, con)
(обратите внимание, чтоC_optimhess
нет"C_optimhess"
).optim
находится в пакете статистики, поэтому вы можете ввестиstats:::C_optimhess
информацию о вызываемой скомпилированной функции.Скомпилированный код в пакете
Если вы хотите просмотреть скомпилированный код в пакете, вам необходимо скачать / распаковать исходный код пакета. Установленных двоичных файлов недостаточно. Исходный код пакета доступен из того же хранилища CRAN (или CRAN-совместимого), из которого пакет был первоначально установлен.
download.packages()
Функция может получить исходный пакет для вас.Это загрузит исходную версию пакета Matrix и сохранит соответствующий
.tar.gz
файл в текущем каталоге. Исходный код для скомпилированных функций можно найти вsrc
каталоге несжатого и неразделенного файла. Этап распаковки и распаковки может быть выполнен внеR
или изнутриR
с использованиемuntar()
функции. Можно объединить этап загрузки и расширения в один вызов (обратите внимание, что таким образом можно загружать и распаковывать только один пакет за раз):В качестве альтернативы, если разработка пакета осуществляется публично (например, через GitHub , R-Forge или RForge.net ), вы, вероятно, можете просмотреть исходный код в Интернете.
Скомпилированный код в базовом пакете
Некоторые пакеты считаются «базовыми» пакетами. Эти пакеты поставляются с R и их версия заблокирована в версии R. Примеры включают
base
,compiler
,stats
иutils
. Как таковые, они не доступны в виде отдельных загружаемых пакетов в CRAN, как описано выше. Скорее, они являются частью дерева исходных текстов R в отдельных каталогах пакетов/src/library/
. Как получить доступ к источнику R, описано в следующем разделе.Скомпилированный код, встроенный в интерпретатор R
Если вы хотите просмотреть код, встроенный в интерпретатор R, вам необходимо скачать / распаковать исходные коды R; или вы можете просматривать источники онлайн через репозиторий R Subversion или зеркало github Уинстона Чанга .
Новостная статья Уве Лиггеса R (PDF) (стр. 43) является хорошим общим справочным материалом о том, как просматривать исходный код
.Internal
и.Primitive
функции. Основные шаги - сначала поиск имени функции в,src/main/names.c
а затем поиск имени «C-entry» в файлах вsrc/main/*
.источник
RStudio
, он попытается получить источник для функции, над которой находится текстовый курсор, если вы нажметеF2
клавишу.scale
есть S3 - я получил,UseMethod("scale")
а затем использовалgetAnywhere(scale.default)
). Но простые функции работают просто отлично.В дополнение к другим ответам на этот вопрос и его дубликатам, есть хороший способ получить исходный код для функции пакета без необходимости знать, в каком пакете он находится. Например, если нам нужен источник для
randomForest::rfcv()
:Чтобы просмотреть / отредактировать его во всплывающем окне:
Чтобы перенаправить в отдельный файл :
источник
View(foo)
; гдеfoo
была функция из уже загруженного пакета.edit()
открывает текстовый редактор (по выбору пользователя) , в то время какView()
открывает зритель электронной таблицы Excel-типа для данных , последний хорошо подходит для просмотра данных (мульти-столбчатых), но , как правило , ужасно для кода ничего, кроме длины игрушек. Например, как я намекаю, обычно первое, что я хочу сделать при просмотре функции, - это пропустить / свернуть / перебрать всю логику разбора аргументов и действия по умолчанию, чтобы увидеть, что на самом деле делает функция .Это раскрывается при отладке с использованием функции debug (). Предположим, вы хотите увидеть базовый код в функции транспонирования t (). Просто набрав 't', мало что видно.
Но, используя 'debug (functionName)', он раскрывает лежащий в основе код, без внутренних данных.
РЕДАКТИРОВАТЬ: debugonce () выполняет то же самое без необходимости использовать undebug ()
источник
debugonce
вместо этогоdebug
в этом случае.Для не примитивных функций R base включает вызванную функцию,
body()
которая возвращает тело функции. Например, источникprint.Date()
функции может быть просмотрен:будет производить это:
Если вы работаете в скрипте и хотите использовать код функции как символьный вектор, вы можете получить его.
получит вас:
Зачем мне это делать? Я создавал пользовательский объект S3 (
x
, гдеclass(x) = "foo"
) на основе списка. Один из членов списка (названный «fun») был функцией, и я хотелprint.foo()
отобразить исходный код функции с отступом. В итоге я получил следующий фрагментprint.foo()
:который отступает и отображает код, связанный с
x[["fun"]]
.источник
Не видел, как это вписывается в поток основного ответа, но это меня озадачило, поэтому я добавляю его сюда:
Инфиксные операторы
Чтобы увидеть исходный код некоторых операторов базовых инфиксных (например,
%%
,%*%
,%in%
), использованиеgetAnywhere
, например:Основной ответ охватывает, как затем использовать зеркала, чтобы копать глубже.
источник
getAnywhere
. Или вы могли бы просто использовать кавычку , если вы уже знаете имя оператора:`%in%`
.getAnywhere
упоминается и в вашем ответе, но я думаю, что конкретная ссылка на infix полезна для будущей ссылки на этот ответ - я много раз читал эту страницу и все еще был немного озадачен, пытаясь найти код для таких функций для в то время как - и я не думаю, что это вписывается в поток любого другого ответа (которые оба используютgetAnywhere
для другой цели).В R есть очень удобная функция
edit
Он откроет исходный код
optim
использования редактора, указанного в Roptions
, а затем вы сможете отредактировать его и назначить измененную функциюnew_optim
. Мне очень нравится эта функция, чтобы просматривать код или отлаживать код, например, печатать некоторые сообщения или переменные или даже назначать их глобальным переменным для дальнейшего исследования (конечно, вы можете использоватьdebug
).Если вы просто хотите просмотреть исходный код и не хотите, чтобы раздражающий длинный исходный код печатался на вашей консоли, вы можете использовать
Ясно, что это нельзя использовать для просмотра исходного кода на C / C ++ или Fortran.
Кстати,
edit
может открывать другие объекты, такие как список, матрица и т. Д., Которые затем отображают структуру данных с атрибутами. Функциюde
можно использовать для открытия редактора, похожего на Excel (если GUI поддерживает его), для изменения матрицы или фрейма данных и возврата нового. Иногда это удобно, но в обычном случае этого следует избегать, особенно если у вас большая матрица.источник
Пока функция написана на чистом R, а не на C / C ++ / Fortran, можно использовать следующее. В противном случае лучший способ - это отладка и использование « перехода в »:
источник
body
.identical(functionBody, body)
естьTRUE
.base::body
иmethods::functionBody
, хотя они не любят отделяться.body
также может быть переопределено: rdocumentation.org/search?q=bodyВ RStudio есть (как минимум) 3 способа:
View
(имя_функции) (как указано выше)Откроется новая панель с исходным кодом. Если вы достигнете .Primitive или .C, вам понадобится другой метод, извините.
источник
View([function_name])
- напримерView(mean)
Обязательно используйте прописные буквы [V]. Код только для чтения откроется в редакторе.источник
Вы также можете попытаться использовать
print.function()
, что является универсальным S3, чтобы получить функцию записи в консоли.источник
print.function()
это метод S3 . Универсальный естьprint()
. И вообще не стоит вызывать методы напрямую. Это наносит ущерб всей цели универсальных функций и методов отправки.