Saya ingin melihat kode sumber untuk suatu fungsi untuk melihat cara kerjanya. Saya tahu saya bisa mencetak fungsi dengan mengetik namanya saat diminta:
> t
function (x)
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>
Dalam hal ini, apa UseMethod("t")
artinya? Bagaimana cara menemukan kode sumber yang sebenarnya digunakan oleh, misalnya t(1:10)
:?
Apakah ada perbedaan antara ketika saya melihat UseMethod
dan ketika saya melihat standardGeneric
dan showMethods
, seperti halnya 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.
Dalam kasus lain, saya dapat melihat bahwa fungsi R dipanggil, tetapi saya tidak dapat menemukan kode sumber untuk fungsi tersebut.
> 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
Bagaimana cara menemukan fungsi seperti .cbindts
dan .makeNamesTs
?
Masih dalam kasus lain, ada sedikit kode R, tetapi sebagian besar pekerjaan tampaknya dilakukan di tempat lain.
> 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")
Bagaimana saya mencari tahu apa .Primitive
fungsinya? Demikian pula, beberapa fungsi panggilan .C
, .Call
, .Fortran
, .External
, atau .Internal
. Bagaimana saya dapat menemukan kode sumber untuk itu?
Jawaban:
UseMethod("t")
memberitahu Anda bahwa itut()
adalah fungsi generik ( S3 ) yang memiliki metode untuk kelas objek yang berbeda.Sistem pengiriman metode S3
Untuk kelas S3, Anda dapat menggunakan
methods
fungsi ini untuk membuat daftar metode untuk fungsi atau kelas generik tertentu."Fungsi yang tidak terlihat ditandai bintang" berarti fungsi tersebut tidak diekspor dari namespace paketnya. Anda masih dapat melihat kode sumbernya melalui
:::
fungsi (yaitustats:::t.ts
), atau dengan menggunakangetAnywhere()
.getAnywhere()
berguna karena Anda tidak perlu tahu dari paket mana fungsi itu berasal.Sistem pengiriman metode S4
Sistem S4 adalah sistem pengiriman metode yang lebih baru dan merupakan alternatif dari sistem S3. Berikut adalah contoh fungsi S4:
Outputnya sudah menawarkan banyak informasi.
standardGeneric
adalah indikator fungsi S4. Metode untuk melihat metode S4 yang ditentukan ditawarkan dengan sangat membantu:getMethod
dapat digunakan untuk melihat kode sumber dari salah satu metode:Ada juga metode dengan tanda tangan yang lebih kompleks untuk setiap metode, misalnya
Untuk melihat kode sumber untuk salah satu metode ini seluruh tanda tangan harus disediakan, mis
Tidak cukup untuk memasok sebagian tanda tangan
Fungsi yang memanggil fungsi yang tidak diekspor
Dalam kasus
ts.union
,.cbindts
dan.makeNamesTs
merupakan fungsi yang tidak diekspor daristats
namespace. Anda dapat melihat kode sumber fungsi yang tidak diekspor dengan menggunakan:::
operator ataugetAnywhere
.Fungsi yang memanggil kode yang dikompilasi
Perhatikan bahwa "dikompilasi" tidak merujuk ke kode R byte-dikompilasi seperti yang dibuat oleh paket kompiler . The
<bytecode: 0x294e410>
baris dalam output di atas menunjukkan bahwa fungsi ini byte-dikompilasi, dan Anda masih dapat melihat sumber dari baris perintah R.Fungsi panggilan
.C
,.Call
,.Fortran
,.External
,.Internal
, atau.Primitive
menelepon titik masuk dalam kode dikompilasi, sehingga Anda akan harus melihat sumber kode dikompilasi jika Anda ingin memahami fungsi. Ini cermin GitHub dari kode sumber R adalah tempat yang layak untuk memulai. Fungsi inipryr::show_c_source
bisa menjadi alat yang berguna karena akan membawa Anda langsung ke halaman GitHub untuk.Internal
dan.Primitive
menelepon. Paket dapat menggunakan.C
,.Call
,.Fortran
, dan.External
; tetapi tidak.Internal
atau.Primitive
, karena ini digunakan untuk memanggil fungsi-fungsi yang dibangun ke dalam interpreter R.Panggilan ke beberapa fungsi di atas dapat menggunakan objek, bukan string karakter untuk referensi fungsi yang dikompilasi. Dalam kasus tersebut, objek adalah kelas
"NativeSymbolInfo"
,"RegisteredNativeSymbol"
atau"NativeSymbol"
; dan mencetak objek menghasilkan informasi yang bermanfaat. Misalnya,optim
panggilan.External2(C_optimhess, res$par, fn1, gr1, con)
(perhatikan ituC_optimhess
, bukan"C_optimhess"
).optim
ada dalam paket statistik, jadi Anda bisa mengetikstats:::C_optimhess
untuk melihat informasi tentang fungsi yang dikompilasi dipanggil.Kode yang dikompilasi dalam sebuah paket
Jika Anda ingin melihat kode yang dikompilasi dalam sebuah paket, Anda perlu mengunduh / membongkar sumber paket. Binari yang diinstal tidak cukup. Kode sumber suatu paket tersedia dari repositori CRAN yang sama (atau yang kompatibel dengan CRAN) tempat asal paket tersebut. The
download.packages()
Fungsi bisa mendapatkan sumber paket untuk Anda.Ini akan mengunduh versi sumber paket Matrix dan menyimpan
.tar.gz
file yang sesuai di direktori saat ini. Kode sumber untuk fungsi-fungsi yang dikompilasi dapat ditemukan disrc
direktori file yang tidak dikompresi dan tidak dikompilasi. Langkah uncompressing dan unfaring dapat dilakukan di luarR
, atau dari dalamR
menggunakanuntar()
fungsi. Dimungkinkan untuk menggabungkan langkah unduhan dan perluasan menjadi satu panggilan (perhatikan bahwa hanya satu paket pada satu waktu yang dapat diunduh dan dibuka dengan cara ini):Atau, jika pengembangan paket di-host secara publik (misalnya melalui GitHub , R-Forge , atau RForge.net ), Anda mungkin dapat menelusuri kode sumber online.
Kode yang dikompilasi dalam paket dasar
Paket tertentu dianggap paket "basis". Paket-paket ini kapal dengan R dan versi mereka dikunci ke versi R. Contohnya termasuk
base
,compiler
,stats
, danutils
. Dengan demikian, mereka tidak tersedia sebagai paket yang dapat diunduh terpisah pada CRAN seperti dijelaskan di atas. Sebaliknya, mereka adalah bagian dari pohon sumber R dalam direktori paket individu di bawah/src/library/
. Cara mengakses sumber R dijelaskan di bagian selanjutnya.Kode yang dikompilasi dibangun ke dalam interpreter R
Jika Anda ingin melihat kode bawaan ke interpreter R, Anda perlu mengunduh / membongkar sumber R; atau Anda dapat melihat sumber secara online melalui repositori R Subversion atau mirror github Winston Chang .
Artikel berita Uwe Ligges (PDF) (hlm. 43) adalah referensi umum yang baik tentang cara melihat kode sumber
.Internal
dan.Primitive
fungsinya. Langkah-langkah dasar adalah pertama-tama mencari nama fungsi disrc/main/names.c
dan kemudian mencari nama "entri-C" dalam file disrc/main/*
.sumber
RStudio
, itu akan berusaha untuk menarik sumber untuk fungsi kursor teks Anda selesai jika Anda menekanF2
tombol.scale
, yaitu S3 - saya dapatkanUseMethod("scale")
dan kemudian digunakangetAnywhere(scale.default)
). Tapi fungsi polos bekerja dengan baik.Selain jawaban lain pada pertanyaan ini dan duplikatnya, berikut ini adalah cara yang baik untuk mendapatkan kode sumber untuk fungsi paket tanpa perlu mengetahui paket yang ada di dalamnya. Misalnya jika kita menginginkan sumber untuk
randomForest::rfcv()
:Untuk melihat / mengeditnya di jendela sembulan:
Untuk mengalihkan ke file terpisah :
sumber
View(foo)
; di manafoo
fungsi dari paket yang sudah dimuat.edit()
membuka editor teks (pilihan pengguna) , sedangkanView()
membuka penampil spreadsheet tipe-Excel untuk data , yang terakhir baik untuk menelusuri data (multi-kolom), tetapi biasanya mengerikan untuk kode apa pun selain panjang mainan. Misalnya seperti yang saya mengisyaratkan, umumnya hal pertama yang ingin saya lakukan saat browsing fungsi adalah melewatkan / runtuhnya / boneka keluar semua arg-parsing dan default-tindakan logika, untuk melihat apa fungsi sebenarnya tidak .Itu terungkap ketika Anda debug menggunakan fungsi debug (). Misalkan Anda ingin melihat kode yang mendasari dalam fungsi t () transpos. Hanya mengetik 't', tidak banyak mengungkapkan.
Tapi, Menggunakan 'debug (functionName)', ia mengungkapkan kode yang mendasarinya, tanpa internal.
EDIT: debugonce () menyelesaikan hal yang sama tanpa harus menggunakan undebug ()
sumber
debugonce
daripadadebug
dalam hal ini.Untuk fungsi non-primitif, basis R mencakup fungsi yang disebut
body()
mengembalikan fungsi tubuh. Misalnya sumberprint.Date()
fungsi dapat dilihat:akan menghasilkan ini:
Jika Anda bekerja dalam skrip dan ingin kode fungsi sebagai vektor karakter, Anda bisa mendapatkannya.
akan membuat Anda:
Mengapa saya ingin melakukan hal seperti itu? Saya sedang membuat objek S3 khusus (
x
, di manaclass(x) = "foo"
) berdasarkan daftar. Salah satu anggota daftar (bernama "kesenangan") adalah fungsi dan saya inginprint.foo()
menampilkan kode sumber fungsi, indentasi. Jadi saya berakhir dengan cuplikan berikut diprint.foo()
:yang indentasi dan menampilkan kode yang terkait dengan
x[["fun"]]
.sumber
Tidak melihat bagaimana ini cocok dengan aliran jawaban utama tetapi itu membuat saya bingung untuk sementara waktu jadi saya menambahkannya di sini:
Operator Infix
Untuk melihat kode sumber dari beberapa operator dasar infix (misalnya,
%%
,%*%
,%in%
), penggunaangetAnywhere
, misalnya:Jawaban utamanya mencakup bagaimana cara menggunakan mirror untuk menggali lebih dalam.
sumber
getAnywhere
. Atau Anda bisa menggunakan tanda kutip mundur jika Anda sudah tahu nama operator:`%in%`
.getAnywhere
disebutkan dalam jawaban Anda juga, tetapi saya pikir referensi khusus untuk infix berguna untuk referensi di masa mendatang untuk jawaban ini - saya telah membaca halaman ini berkali-kali dan masih agak bingung mencoba menemukan kode untuk fungsi-fungsi tersebut untuk suatu sementara - dan saya tidak berpikir itu cocok dengan aliran jawaban lain (yang keduanya menggunakangetAnywhere
untuk tujuan lain).Ada fungsi yang sangat berguna di R
edit
Ini akan membuka kode sumber
optim
menggunakan editor yang ditentukan dalam R'soptions
, dan kemudian Anda dapat mengeditnya dan menetapkan fungsi yang dimodifikasinew_optim
. Saya sangat menyukai fungsi ini untuk melihat kode atau men-debug kode, misalnya, mencetak beberapa pesan atau variabel atau bahkan menetapkannya ke variabel global untuk penyelidikan lebih lanjut (tentu saja Anda dapat menggunakandebug
).Jika Anda hanya ingin melihat kode sumber dan tidak ingin kode sumber panjang yang mengganggu dicetak di konsol Anda, Anda dapat menggunakannya
Jelas, ini tidak dapat digunakan untuk melihat kode sumber C / C ++ atau Fortran.
BTW,
edit
dapat membuka objek lain seperti daftar, matriks, dll, yang kemudian menunjukkan struktur data dengan atribut juga. Fungside
dapat digunakan untuk membuka editor excel like (jika GUI mendukungnya) untuk memodifikasi matriks atau bingkai data dan mengembalikan yang baru. Ini kadang-kadang berguna, tetapi harus dihindari dalam kasus biasa, terutama ketika matriks Anda besar.sumber
Selama fungsi ini ditulis dalam R murni bukan C / C ++ / Fortran, orang dapat menggunakan yang berikut ini. Kalau tidak, cara terbaik adalah debugging dan menggunakan " lompat ke ":
sumber
body
.identical(functionBody, body)
adalahTRUE
.base::body
danmethods::functionBody
, meskipun mereka tidak suka dihilangkan.body
bisa ditimpa juga: rdocumentation.org/search?q=bodyDi RStudio, ada (setidaknya) 3 cara:
View
(function_name) (seperti yang dinyatakan di atas)Panel baru akan terbuka dengan kode sumber. Jika Anda mencapai .Primitive atau .C Anda akan memerlukan metode lain, maaf.
sumber
View([function_name])
- mis.View(mean)
Pastikan untuk menggunakan huruf besar [V]. Kode baca-saja akan terbuka di editor.sumber
Anda juga dapat mencoba menggunakan
print.function()
, yang merupakan S3 generik, untuk mendapatkan fungsi tulis di konsol.sumber
print.function()
adalah metode S3 . Generiknya adalahprint()
. Dan umumnya bukan ide yang baik untuk memanggil metode secara langsung. Itu mengalahkan seluruh tujuan fungsi generik dan metode pengiriman.