作者 | Tomás Aragón
译者 | 平川
策划 | 刘燕
本文最初发布于 Tomás Aragón 的个人博客。
15 年来,我在加州大学伯克利分校公共卫生学院教授“应用流行病学 R 语言版”课程。我从 21 世纪初就开始教这门课,当时大多数人对 R 不感兴趣。后来,R 越来越受欢迎,我的课程入学率也越来越高。我教授流行病学概念的 R 编程基础。学生们有自己选择的项目。因为他们来自多个学科,所以项目通常非常具有创新性,我也从他们身上学到了很多东西。
在过去的 15 年里,我见证了“数据科学”的兴起,以及学生们在项目中的独创性和创造性。当然,课程也在不断发展。我引入贝叶斯网络作为统一的框架,以引入概率依赖、因果图和决策网络(用于决策分析)。
我开始涉猎 Python。遗憾的是,COVID-19 大流行打断了我的教学,因为我是旧金山的卫生官员兼人口卫生司司长。在大流行应对工作中,我几乎没有时间分析或学习 Python。
不记得是什么时候,我发现了 Julia——一种为科学计算而设计的编程语言,有 Python 或 R 的直观,同时又有 C++ 的速度。我爱上了 Julia,放弃了学习 Python。我过去没有,现在也没有时间在 1.5 种以上的编程语言中保持核心竞争力。随着我对 Julia 的了解越来越多,我开始确信,对我来说,学习 Julia 是比坚持学习 R 更好的长期投资。
我使用编程来探索或测试我的流行病学直觉,学习新的方法,并可视化和分析数据。我个人对贝叶斯网络、决策网络、因果推理、马尔可夫决策过程和基于代理的建模很感兴趣。
以下是我认为流行病学家应该会看重的 Julia 的一些关键特性:
  • 多重指派
  • 复合类型
  • 即时编译
  • 速度(非常快)
  • 社区
Julia 编程更直观。例如,在 R 中,我们会设法避免循环,因为它们的效率非常低。而在 Julia 中,循环很高效,因为它在执行之前编译,使得编程更加自然。
下面我将用一个简单的示例演示多重指派。R 是单指派的。
Julia 多重指派示例
我是 R ' epitools '包的创始开发者。我开发了基本流行病学分析函数(如 2x2 表),其中几个来自 Rothman 的“现代流行病学”教科书。例如,如果我想创建一个函数来计算一个 2x2 列联表的优势比(odds ratio),数据可以通过以下几种方式提供:
  • 四个整数
  • 两个比例
  • 一个 2x2 表(矩阵)
  • 两个带有分类数据的向量
如果我想编写一个函数,将这些可能的数据类型作为参数来处理,那么为了调用下一个函数(嵌套的或外部的),就必须对数据类型进行大量的处理和检查。这需要做大量不必要的工作。我们看看使用 Julia 的多重指派如何实现。
2003 年,我们发表了一项研究,证据了饮用未经过滤的城市自来水与晚期 HIV 疾病患者患隐孢子虫病有关。以下是这篇论文中的列联表:
我们计算下最高暴露类别和最低暴露类别之间未经调整的优势比。以下是这个计算的 2x2 表:
对于一个适当的结构化表格,优势比是交叉积:
对于病例对照设计,优势比是暴露优势比:
我们将创建三个函数,它们可以接收以下三种不同类型的参数来计算优势比:
  • 四个整数
  • 两个比例
  • 一个 2x2 表(矩阵)
有个问题是,这三个函数的名称相同:oddsratio。在 Julia 中,这是可能的,因为它有多重指派。相比之下,R 是单指派的。
## 函数 1function oddsratio(a::Int, b::Int, c::Int, d::Int) or = (a * d) / (b * c) return orend oddsratio (generic function with 1 method)
我们将 2x2 表的 4 个整数作为参数传递给 oddsratio 以测试这个函数:
oddsratio(12, 6, 2, 29)29.0
下面是第二个函数,处理比例参数;例如,比较病例和对照组的暴露优势比。
## 函数 2function oddsratio(p1::Float64, p0::Float64) or = ((p1)/(1 - p1)) / ((p0)/(1 - p0)) return orendoddsratio (generic function with 2 methods)
我们将 2x2 表的 2 个比例作为参数传递给 oddsratio 以测试这个函数:
prop1 = 12 / (12 + 2) # probability of exposure among casesprop0 = 6 / (6 + 29) # probability of exposure among controlsoddsratio(prop1, prop0)28.999999999999982
最后,第 3 个函数处理一个 2x2 表(矩阵)参数:
## 函数 3function oddsratio(x::Matrix{Int}) or = (x[1, 1] * x[2, 2]) / (x[1, 2] * x[2, 1]) return orendoddsratio (generic function with 3 methods)
我们将 2x2 表作为参数传递给 oddsratio 以测试这个函数:
tab = [12 6; 2 29]2×2 Matrix{Int64}: 12 6 2 29oddsratio(tab)29.0
这称为多重指派。oddsratio 函数有 3 个方法,可以处理多种数据类型。请注意,这有多简单。
以下是泛型函数 oddsratio 的 3 个方法:
  • oddsratio(a::Int64, b::Int64, c::Int64, d::Int64) in Main at In[2]:2
  • oddsratio(p1::Float64, p0::Float64) in Main at In[4]:2
  • oddsratio(x::Matrix{Int64}) in Main at In[6]:2
小  结
在这篇博文中,我总结了自己为什么从 R 转到 Julia。我通过函数演示了多重指派。请注意,创建一个 oddsratio 函数,提供三个方法来处理不同的参数数据类型(整数、比例和矩阵),是多么简单。
我喜欢 Julia,你也会喜欢的。你还可以从 Julia 运行 R 或 Python,而且不会有任何中断。
我将发布一些简单的例子,着重突出 Julia 应用于基础流行病学或流行病学编程的特性。
附录
Julia 在创建函数方面非常灵活。以下是三个同名函数的缩写形式。
## 函数 1oddsratio(a::Int, b::Int, c::Int, d::Int) = (a * d) / (b * c)oddsratio (generic function with 3 methods)## 函数 2oddsratio(p1::Float64, p0::Float64) = ((p1)/(1 - p1)) / ((p0)/(1 - p0))oddsratio (generic function with 3 methods)## 函数 3oddsratio(x::Matrix{Int}) = (x[1, 1] * x[2, 2]) / (x[1, 2] * x[2, 1])oddsratio (generic function with 3 methods)
以我带有偏见的眼光来看,Julia 有一种 R 所缺乏的简单和优雅。
声明:本文为 InfoQ 翻译,未经许可禁止转载。
原文链接:
https://drtomasaragon.github.io/posts/2023-01-14-my-journey-from-r-to-julia/

你也「在看」吗? 👇
继续阅读
阅读原文