RCall 把一个完整的 R 会话嵌进 Julia:
R字符串跑任意 R 代码、@rput/@rget双向搬变量、R"""..."""跑多行脚本。统计检验、专业统计模型这些 R 的看家本领,不用离开 Julia 就能用。
] add RCall using RCall R"1 + 1" # R 字符串宏,直接求值 R"mean(rnorm(100))"
x = randn(1000) group = repeat(["A", "B"], 500) @rput x group # Julia 变量进入 R 会话 R"t.test(x ~ group)" # 用 R 做 t 检验 result = R"t.test(x ~ group)" rcopy(result) # R 对象转回 Julia(列表/具名元组) pval = rcopy(R"t.test(x ~ group)$p.value") # 只取 p 值,得到 Float64
rcopy 是类型转换的关口:R 的 list 变 Julia 的 Dict 或具名元组,data.frame 变 DataFrame(配 RData 集成时自动完成)。
R""" library(ggplot2) df <- data.frame(x = $x) # $ 引用 Julia 变量 p <- ggplot(df, aes(x = x)) + geom_histogram(bins = 30) ggsave("hist_from_julia.png", p) """
注意 $x 插值——Julia 变量直接进 R 表达式,不用先 @rput。
| 任务 | 建议 |
|---|---|
| 数据清洗、数值建模 | 留在 Julia(DataFrames + 各领域库) |
| 特殊统计检验、生信分析流程 | RCall 借用 R 包 |
| ggplot2 风格出版图 | 个人偏好决定,Makie 也能做 |
| 大规模机器学习 | Julia Flux 或回 Python 生态 |
⚠️ 常见坑:RCall 需要本机装有 R 运行时,且 Julia 与 R 的位数(64 位)要一致;首次
using RCall时按提示配置 R 主目录,找不到 R 会直接报错。
💡 关键直觉:RCall 的定位是"逃生舱"而不是"常住民"。能在 Julia 生态里解决的,别为了熟悉感绕道 R——每跨一次语言边界,就多一处类型转换的出错面。
背景:实验数据在 Julia 里做清洗与聚合(数据量大,Julia 快),统计检验与出版图用 R 的成熟包(ggplot2 与某专业检验只有 R 版)。完整走一遍。第一步,Julia 侧准备数据并搬运:
using RCall, Random Random.seed!(42) julia_v = vcat(randn(200), randn(200) .+ 0.4) # 两组有差异的样本 julia_g = repeat(["control", "treated"], inner = 200) @rput julia_v julia_g # 两个变量同时进入 R 会话
第二步,R 侧做检验并画图,结果直接落盘:
R""" res <- wilcox.test(julia_v ~ julia_g) # 非参数检验,不假设正态 print(res$p.value) library(ggplot2) df <- data.frame(v = julia_v, g = julia_g) p <- ggplot(df, aes(x = g, y = v, fill = g)) + geom_boxplot() + theme_minimal() ggsave("group_compare.png", p, width = 5, height = 4) """
第三步,把检验结果取回 Julia 继续用(比如汇总进报告表):
pval = rcopy(R"wilcox.test(julia_v ~ julia_g)$p.value") # Float64,约 1e-6 量级,可直接进 Julia 侧的结果表
解读:整条流水线只跨了两次边界(送数据、取 p 值),重活都在各自语言里批量完成,符合混编的"少过桥"原则。变式:把三步包进函数、参数化组数与检验方法,就是一个可复用的分析组件;若 R 会话状态被污染,R"rm(list=ls())" 清场重来。
RCall 的报错集中在环境与转换两侧。环境侧:首次 using RCall 找不到 R,按提示设置 R 主目录(装 R 时记住安装路径);Julia 与 R 必须同为 64 位,混装会报奇怪的加载失败。转换侧:rcopy 对复杂 R 对象(含 S4 类、因子)可能给出不完整的 Julia 表示,策略是别整对象搬、在 R 侧先把要的字段抽成原子向量再取回;因子取回是 PooledArray,做数值运算前先转 Vector{String} 或映射等级。还有一个隐蔽点:R 的整数是 32 位,rcopy 后得到 Int32,与 Julia 惯用的 Int64 混算会触发类型提升,聚合统计前统一 Int.(x) 一下可避免莫名其妙的类型告警。
RCall 其实提供了不止一种用法,分清形态能解释很多"别人的代码为什么那样写"。形态一是 R"..." 字符串求值,适合一两行的临时调用;形态二是 @rput/@rget 变量搬运,适合成批的数据交接,变量名在两侧保持一致、排查最方便;形态三是 R""...""" 多行块配合 $ 插值,适合整段 R 脚本(含 ggplot2 这类管道式图形语法)。三者背后是同一个持久 R 会话,所以混用完全合法——先用 @rput 送数据、再用插值版脚本画图、最后 rcopy 取统计量,正是本节案例的组合。另有 @r_str 与 REPL 的 R 模式(按 $ 切换)属于锦上添花,用熟三种主形态后再探索不迟。理解"共享会话"这一点还能解开一个常见疑惑:R 侧的变量在多次调用间一直存在,长会话里注意命名不要互相覆盖。
R"代码" 单行、R"""...""" 多行,$ 可插 Julia 变量;@rput / @rget / rcopy 三条搬运通道;