我从 R 转向 Julia 的旅程

新闻资讯   2023-06-07 14:03   67   0  


作者 | 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 orend
oddsratio (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 orend
oddsratio (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/


你也「在看」吗? 👇

文章引用微信公众号"AI前线",如有侵权,请联系管理员删除!

博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。