GitHub → https://bit.ly/2V4mtwG
※20分しかないので簡単に。
result <- 1 + 2
print(result)
[1] 3
とくに result <- 1 + 1
の部分
「Rのすべての関数はオブジェクトであり、すべてのオブジェクトは関数である。」
↓
「R上での全ての挙動は関数の実行である。」
print(result)
[1] 3
print.default()
が実行されているprint()
は 総称関数 と呼ばれる関数で、引数の中身(のクラス)によって特定の関数が呼び出されるhead()
, plot()
, summary()
などUseMethod("")
という表示が出てくるprint
function (x, ...)
UseMethod("print")
<bytecode: 0x7f9d26f70a28>
<environment: namespace:base>
メソッド一覧は methods()
関数で見る
methods("print")
[1] print.AES*
[2] print.Arima*
[3] print.AsIs
[4] print.Bibtex*
[5] print.CRAN_package_reverse_dependencies_and_views*
[6] print.DLLInfo
[7] print.DLLInfoList
[8] print.DLLRegisteredRoutines
[9] print.Date
[10] print.Dlist
[11] print.HoltWinters*
[12] print.LaTeX*
[13] print.Latex*
[14] print.MethodsFunction*
[15] print.NativeRoutineList
[16] print.PDF_Array*
[17] print.PDF_Dictionary*
[18] print.PDF_Indirect_Reference*
[19] print.PDF_Keyword*
[20] print.PDF_Name*
[21] print.PDF_Stream*
[22] print.PDF_String*
[23] print.POSIXct
[24] print.POSIXlt
[25] print.RGBcolorConverter*
[26] print.Rcpp_stack_trace*
[27] print.Rd*
[28] print.StructTS*
[29] print.TukeyHSD*
[30] print.acf*
[31] print.anova*
[32] print.aov*
[33] print.aovlist*
[34] print.ar*
[35] print.arima0*
[36] print.aspell*
[37] print.aspell_inspect_context*
[38] print.bibentry*
[39] print.browseVignettes*
[40] print.by
[41] print.bytes*
[42] print.changedFiles*
[43] print.checkDocFiles*
[44] print.checkDocStyle*
[45] print.checkFF*
[46] print.checkRd*
[47] print.checkReplaceFuns*
[48] print.checkS3methods*
[49] print.checkTnF*
[50] print.checkVignettes*
[51] print.check_Rd_contents*
[52] print.check_Rd_line_widths*
[53] print.check_Rd_metadata*
[54] print.check_Rd_xrefs*
[55] print.check_RegSym_calls*
[56] print.check_T_and_F*
[57] print.check_code_usage_in_package*
[58] print.check_compiled_code*
[59] print.check_demo_index*
[60] print.check_depdef*
[61] print.check_details*
[62] print.check_details_changes*
[63] print.check_doi_db*
[64] print.check_dotInternal*
[65] print.check_make_vars*
[66] print.check_nonAPI_calls*
[67] print.check_package_CRAN_incoming*
[68] print.check_package_code_assign_to_globalenv*
[69] print.check_package_code_attach*
[70] print.check_package_code_data_into_globalenv*
[71] print.check_package_code_startup_functions*
[72] print.check_package_code_syntax*
[73] print.check_package_code_unload_functions*
[74] print.check_package_compact_datasets*
[75] print.check_package_datasets*
[76] print.check_package_depends*
[77] print.check_package_description*
[78] print.check_package_description_encoding*
[79] print.check_package_license*
[80] print.check_packages_in_dir*
[81] print.check_packages_used*
[82] print.check_po_files*
[83] print.check_pragmas*
[84] print.check_so_symbols*
[85] print.check_url_db*
[86] print.check_vignette_index*
[87] print.citation*
[88] print.codoc*
[89] print.codocClasses*
[90] print.codocData*
[91] print.colorConverter*
[92] print.compactPDF*
[93] print.condition
[94] print.connection
[95] print.data.frame
[96] print.default
[97] print.dendrogram*
[98] print.density*
[99] print.difftime
[100] print.dist*
[101] print.dummy_coef*
[102] print.dummy_coef_list*
[103] print.ecdf*
[104] print.eigen
[105] print.factanal*
[106] print.factor
[107] print.family*
[108] print.fileSnapshot*
[109] print.findLineNumResult*
[110] print.formula*
[111] print.fseq*
[112] print.ftable*
[113] print.function
[114] print.getAnywhere*
[115] print.glm*
[116] print.hclust*
[117] print.help_files_with_topic*
[118] print.hexmode
[119] print.hsearch*
[120] print.hsearch_db*
[121] print.htest*
[122] print.html*
[123] print.html_dependency*
[124] print.infl*
[125] print.integrate*
[126] print.isoreg*
[127] print.kmeans*
[128] print.knitr_kable*
[129] print.libraryIQR
[130] print.listof
[131] print.lm*
[132] print.loadings*
[133] print.loess*
[134] print.logLik*
[135] print.ls_str*
[136] print.medpolish*
[137] print.mtable*
[138] print.news_db*
[139] print.nls*
[140] print.no
[141] print.noquote
[142] print.numeric_version
[143] print.object_size*
[144] print.octmode
[145] print.packageDescription*
[146] print.packageIQR*
[147] print.packageInfo
[148] print.packageStatus*
[149] print.pairwise.htest*
[150] print.pdf_doc*
[151] print.pdf_fonts*
[152] print.pdf_info*
[153] print.person*
[154] print.power.htest*
[155] print.ppr*
[156] print.prcomp*
[157] print.princomp*
[158] print.proc_time
[159] print.raster*
[160] print.recordedplot*
[161] print.restart
[162] print.rle
[163] print.roman*
[164] print.root_criterion*
[165] print.sessionInfo*
[166] print.shiny.tag*
[167] print.shiny.tag.list*
[168] print.simple.list
[169] print.smooth.spline*
[170] print.socket*
[171] print.srcfile
[172] print.srcref
[173] print.stepfun*
[174] print.stl*
[175] print.subdir_tests*
[176] print.summarize_CRAN_check_status*
[177] print.summary.aov*
[178] print.summary.aovlist*
[179] print.summary.ecdf*
[180] print.summary.glm*
[181] print.summary.lm*
[182] print.summary.loess*
[183] print.summary.manova*
[184] print.summary.nls*
[185] print.summary.packageStatus*
[186] print.summary.ppr*
[187] print.summary.prcomp*
[188] print.summary.princomp*
[189] print.summary.table
[190] print.summary.warnings
[191] print.summaryDefault
[192] print.table
[193] print.tables_aov*
[194] print.terms*
[195] print.ts*
[196] print.tskernel*
[197] print.tukeyline*
[198] print.tukeysmooth*
[199] print.undoc*
[200] print.vignette*
[201] print.warnings
[202] print.xfun_raw_string*
[203] print.xfun_strict_list*
[204] print.xgettext*
[205] print.xngettext*
[206] print.xtabs*
see '?methods' for accessing help and source code
どのメソッドがディスパッチされたかは sloop::s3_dispatch()
でわかる
# install.packages("sloop")
sloop::s3_dispatch(print(result))
print.double
print.numeric
=> print.default
print.default
function (x, digits = NULL, quote = TRUE, na.print = NULL, print.gap = NULL,
right = FALSE, max = NULL, useSource = TRUE, ...)
{
noOpt <- missing(digits) && missing(quote) && missing(na.print) &&
missing(print.gap) && missing(right) && missing(max) &&
missing(useSource) && missing(...)
.Internal(print.default(x, digits, quote, na.print, print.gap,
right, max, useSource, noOpt))
}
<bytecode: 0x7f9d28d23a20>
<environment: namespace:base>
「Rのすべての関数はオブジェクトであり、すべてのオブジェクトは関数である。」
演算子も関数→関数名()
という書き方ができるはず!
`+`(1, 2) # 1 + 1 と同じ
[1] 3
`<-`(a, 1 + 2) # a <- 1 + 2 と同じ
print(a)
[1] 3
※これはあくまで「演算子も関数であるというのを分かりやすくしているだけなので、Rでは普通こういう書き方はしません。(Lispっぽい書き方)」
install.packages("pryr")
install.packages("lobstr")
install.packages("sloop")
install.packages("rlang")
注)dplyrの前身のplyrというパッケージがありましたがそれとは別物です
1 + 2
を読み解くlobstr::ast()
または pryr::ast()
で構造を確認lobstr::ast(1 + 2)
█─`+`
├─1
└─2
1 + 2
[1] 3
言い換えると、「`+`()
関数が実行されるときに何が起こっているのか」
`+()`
関数の中身`+`()
関数 )が呼び出されたとき、それを探しに行きます。.GlobalEnv
ls(pos = .GlobalEnv)
[1] "Q" "a" "print.no" "result"
rlang::env_parent()
でrlang::env_parent(.GlobalEnv)
<environment: package:stats>
attr(,"name")
[1] "package:stats"
attr(,"path")
[1] "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/stats"
rlang::env_parents()
でrlang::env_parents(.GlobalEnv)
[[1]] $ <env: package:stats>
[[2]] $ <env: package:graphics>
[[3]] $ <env: package:grDevices>
[[4]] $ <env: package:utils>
[[5]] $ <env: package:datasets>
[[6]] $ <env: package:methods>
[[7]] $ <env: Autoloads>
[[8]] $ <env: package:base>
[[9]] $ <env: empty>
search()
でも良い
`+`()
は誰が持ってるの?pryr::where("+")
<environment: base>
find()
でも良い
1 + 2
は `+`(1, 2)
を実行した結果である。`+`()
関数はbaseパッケージが持っていて、そこから呼び出される`+()`
関数の中身`+`()
関数の中身を見ると…`+`
function (e1, e2) .Primitive("+")
.Primitive()
.Interenal
というのもあります。.Primitive()
その2environment: 環境
func_name <- (arg1, arg2, ...) {
do something
}
.Primitive()
の関数だけは例外なぜならば、Rのコードが含まれないから
body(`+`)
NULL
formals(`+`)
NULL
environment(`+`)
NULL
src/main/names.c
からCで定義された関数を見つけるpryr::show_c_source()
を使うと簡単pryr::show_c_source()
> pryr::show_c_source(.Primitive("+"))
+ is implemented by do_arith with op = PLUSOP
すごく単純なコードでも、また違って見えて面白いですね
result <- 1 + 2
print(result)
[1] 3
result <- 1 + 2
は `<- `(result, `+`(1, 2))
を実行した結果である。`+`()
関数はbaseパッケージが (という環境) が持って、そこから呼び出される`<-()`
関数も同じ`+`()
関数は .Primitive("+")
というRのソースコード(C言語)の中で定義された関数が呼び出されたものだった%>%
)のソースコードが読めるようになるR言語徹底解説 (原著: Advanced R)