[解決済み] 関数のソースコードを見るにはどうしたらいいですか?
質問
ある関数のソースコードを見て、その動作を確認したい。プロンプトに関数の名前を入力すれば、関数を表示できることは知っています。
> 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
関数を使用すると、特定の汎用関数やクラスのメソッドを一覧表示できます。
> methods(t)
[1] t.data.frame t.default t.ts*
Non-visible functions are asterisked
> methods(class="ts")
[1] aggregate.ts as.data.frame.ts cbind.ts* cycle.ts*
[5] diffinv.ts* diff.ts kernapply.ts* lines.ts
[9] monthplot.ts* na.omit.ts* Ops.ts* plot.ts
[13] print.ts time.ts* [<-.ts* [.ts*
[17] t.ts* window<-.ts* window.ts*
Non-visible functions are asterisked
可視でない関数にはアスタリスクが付けられますが、これはその関数がパッケージの名前空間からエクスポートされていないことを意味します。 その関数のソースコードは
:::
関数(例.
stats:::t.ts
を使用するか、または
getAnywhere()
.
getAnywhere()
は、関数がどのパッケージから来たものかを知る必要がないので便利です。
> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
registered S3 method for t from namespace stats
namespace:stats
with value
function (x)
{
cl <- oldClass(x)
other <- !(cl %in% c("ts", "mts"))
class(x) <- if (any(other))
cl[other]
attr(x, "tsp") <- NULL
t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>
S4方式のディスパッチシステム
S4方式は、S3方式に代わる新しい方式派遣方式です。以下は、S4関数の例です。
> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"
function (x, ...)
standardGeneric("chol2inv")
<bytecode: 0x000000000eafd790>
<environment: 0x000000000eb06f10>
Methods may be defined for arguments: x
Use showMethods("chol2inv") for currently available ones.
出力はすでに多くの情報を提供しています。
standardGeneric
はS4関数のインジケータである。定義されたS4メソッドを見るためのメソッドが提供されているのが便利です。
> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"
getMethod
は、あるメソッドのソースコードを見るために使うことができます。
> getMethod("chol2inv", "diagonalMatrix")
Method Definition:
function (x, ...)
{
chk.s(...)
tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>
Signatures:
x
target "diagonalMatrix"
defined "diagonalMatrix"
また、各メソッドにもっと複雑なシグネチャを持つメソッドもあり、例えば
require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"
これらのメソッドのソースコードを見るには、シグネチャ全体を指定する必要があります(例)。
getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )
部分署名を提供するだけでは十分ではありません。
getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") :
# No method found for function "extract" and signature SpatialPolygons
未エクスポートの関数を呼び出す関数
の場合
ts.union
,
.cbindts
と
.makeNamesTs
からエクスポートされない関数です。
stats
名前空間を使用します。エクスポートされていない関数のソースコードは
:::
演算子または
getAnywhere
.
> stats:::.makeNamesTs
function (...)
{
l <- as.list(substitute(list(...)))[-1L]
nm <- names(l)
fixup <- if (is.null(nm))
seq_along(l)
else nm == ""
dep <- sapply(l[fixup], function(x) deparse(x)[1L])
if (is.null(nm))
return(dep)
if (any(fixup))
nm[fixup] <- dep
nm
}
<bytecode: 0x38140d0>
<environment: namespace:stats>
コンパイルされたコードを呼び出す関数
によって作成されたバイトコンパイルされたRコードを指しているのではないことに注意してください。
コンパイラ
パッケージで提供されます。また
<bytecode: 0x294e410>
の行は、この関数がバイトコンパイルされていることを示し、Rのコマンドラインからソースを見ることができます。
を呼び出す関数は
.C
,
.Call
,
.Fortran
,
.External
,
.Internal
または
.Primitive
は、コンパイルされたコードのエントリーポイントを呼び出しているので、その機能を完全に理解したい場合は、コンパイルされたコードのソースを見る必要があります。
これは
RのソースコードのGitHubミラーは、その手始めとして適切な場所です。この関数
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 パッケージに含まれているので、以下のように入力します。
stats:::C_optimhess
をクリックすると、呼び出されたコンパイル済み関数の情報が表示されます。
パッケージ内のコンパイル済みコード
パッケージ内のコンパイルされたコードを表示したい場合は、パッケージのソースをダウンロード/アンパックする必要があります。インストールされたバイナリでは不十分です。パッケージのソースコードは、そのパッケージがもともとインストールされたのと同じ CRAN (または CRAN 互換) リポジトリから入手できます。が必要です。
download.packages()
関数は、パッケージのソースを取得することができます。
download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")
これは、Matrix パッケージのソースバージョンをダウンロードし、対応する
.tar.gz
ファイルをカレントディレクトリに保存します。コンパイルされた関数のソースコードは
src
ディレクトリに格納されます。解凍と紐付けのステップは、以下のディレクトリの外で行うことができます。
R
または
R
を使用して
untar()
関数を使用します。ダウンロードと展開のステップを1回の呼び出しにまとめることも可能です(この方法では、一度に1つのパッケージしかダウンロードと展開ができないことに注意してください)。
untar(download.packages(pkgs = "Matrix",
destdir = ".",
type = "source")[,2])
あるいは、パッケージの開発が公にホストされている場合 (たとえば ギットハブ , R-フォージ または RForge.net ) 、おそらくオンラインでソースコードを閲覧することができます。
ベースパッケージに含まれるコンパイル済みコード
ある種のパッケージは、基本パッケージとみなされます。これらのパッケージは R と一緒に出荷され、そのバージョンは R のバージョンにロックされています。
base
,
compiler
,
stats
および
utils
. そのため、これらは上記のようにCRAN上で個別のダウンロード可能なパッケージとして利用することはできません。むしろ、それらはRのソースツリーの一部で
/src/library/
. Rのソースにアクセスする方法については、次のセクションで説明します。
Rインタプリタに組み込まれたコンパイル済みコード
Rインタプリタに組み込まれたコードを表示したい場合は、Rのソースをダウンロード/アンパックする必要があります。 サブバージョンリポジトリ または Winston Changのgithubミラーサイト .
Uwe Liggesの
Rニュース記事(PDF)
(のソースコードの見方については、P.43が一般的な参考となります。
.Internal
と
.Primitive
関数を使用することができます。 基本的な手順は、まず関数名を
src/main/names.c
の中にあるファイルから、Cエントリー名を探します。
src/main/*
.
関連
-
[解決済み] Rの二乗偏差の総和の算出
-
[解決済み] メソッドと関数の違いは何ですか?
-
[解決済み] 関数名を文字列として取得するには?
-
[解決済み] Pythonの変数名や関数名の命名規則について教えてください。
-
[解決済み] なぜ `[`] は `subset` よりも優れているのですか?
-
[解決済み] Rでオブジェクト(変数)が定義されているかどうかを確認するには?
-
[解決済み】JavaScriptの関数にデフォルトのパラメータ値を設定する
-
[解決済み】関数の前のエクスクラメーションマークは何をするのですか?
-
[解決済み】data.table vs dplyr:一方がうまくできない、またはうまくできないことを行うことができますか?
-
[解決済み] 2つの単語の最初の文字を大文字にします。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
R言語エラー:図の余白が大きすぎる 解決方法
-
R plot.new() のエラー : 図形の余白が大きすぎる
-
[解決済み] リストをデータフレームに変換する
-
[解決済み] 統計的最頻値の求め方は?
-
[解決済み] data.frameの1つの列の名前を変更する方法は?
-
[解決済み] 先頭と末尾の空白を削除するにはどうしたらよいですか?
-
[解決済み] Rでオブジェクト(変数)が定義されているかどうかを確認するには?
-
[解決済み】自作関数を書くときにRの省略機能を使うには?
-
[解決済み】ifelse()でDateオブジェクトがnumericオブジェクトにならないようにする方法
-
[解決済み] データフレームのカラムのデータ型を決定する