003:可重复研究概念与想法(第1部分)🔬

003:可重复研究概念与想法(第1部分)🔬在本节课中 我们将学习 可重复研究 的基本概念及其在数据科学中的重要性 我们将探讨为什么确保分析过程可被他人复现至关重要 并简要介绍本课程将涵盖的主要工具和原则 大家好 欢迎来到 可重复研究 课程 这门课是数据科学专业系列的第五门课程 涵盖一个在典型统计或数据分析课程中较少讨论的特殊主题 尽管 可重复研究 一词中包含 研究 但它适用于许多不同领域 不仅限于从事研究的人员 基本理念是

大家好,我是讯享网,很高兴认识大家。这里提供最前沿的Ai技术和互联网信息。



在本节课中,我们将学习“可重复研究”的基本概念及其在数据科学中的重要性。我们将探讨为什么确保分析过程可被他人复现至关重要,并简要介绍本课程将涵盖的主要工具和原则。


大家好,欢迎来到《可重复研究》课程。这门课是数据科学专业系列的第五门课程,涵盖一个在典型统计或数据分析课程中较少讨论的特殊主题。尽管“可重复研究”一词中包含“研究”,但它适用于许多不同领域,不仅限于从事研究的人员。

基本理念是:当你进行数据分析时,涉及许多步骤,包含大量计算,可能还有大量数据操作或处理。在传达你的工作时,必须以他人能够实际重建你所做工作的方式进行沟通,这就是让他人可复现。随着数据分析和数据集变得越来越复杂,确保你所做的工作真正可复现变得越来越困难。有时你会丢失部分代码,有时会忘记某个处理或转换步骤。如果不记录所有这些细节,分析就可能无法复现。

因此,本课程将讨论一些基本工具,帮助你使分析及整体工作可复现。我们将讨论诸如 knitr 等工具,探讨如何在 RStudio 中实现可重复性,并介绍一些基本原则,以确保你的工作尽可能可复现。我们认为,这是任何领域数据分析中非常重要的一个方面,因为它关乎精确传达你的工作,使他人能够理解整个过程。

在课程的最后部分,我们将讨论一些案例研究,展示可重复性实践成功或严重失败的例子。这些案例研究极具启发性,能让你了解什么是可行的,什么是不可行的。

希望你们喜欢这门课程。这是一个非常重要的理念,希望你们能从中获益良多。


本节课中,我们一起学习了“可重复研究”的核心目标——确保数据分析过程可被他人完整复现,并了解了本课程将如何通过介绍工具(如 knitr)、原则和案例研究来帮助我们实现这一目标。

在本节课中,我们将学习可重复研究的基本概念及其重要性。无论你是否自视为研究者,只要涉及数据分析,理解可重复性的理念及其带来的问题都至关重要。


为了介绍可重复性引发的议题,我们可以从另一个领域——音乐——进行类比。

以下是歌曲《Code Monkey》的开头片段。请先听一下这段音乐。

🎼 Code monkey, get up, Get coffee. Code monkey, go to job. Code monkey have boring meeting with boring manager Rob. Rob say cold monkey, very diligent, foot is out st...

这段音乐由Jonathan Colton创作并演唱。你刚刚听到的是歌曲第一分钟左右的片段,包含了第一段主歌。

现在,思考一下你对这首歌已有的了解。你知道它的旋律、创作者、表演者。开头是吉他演奏,如果你听力不错,能听出是F大调。随后另一把吉他加入,还有鼓组伴奏。当然,还有演唱的歌词。如果你仔细听并能理解语言,甚至可以听出他在唱什么。这就是整首歌的基本构成。

大多数这样的歌曲并不复杂。乐器或声部不多,时长通常在2到4分钟。如果你是一位优秀的音乐家,仔细聆听后,自己用吉他或其他乐器演奏这首歌并不算太难。


现在,让我们来听另一段作品。

(播放马勒第八交响曲开头片段)

你可能没听出来,这是古斯塔夫·马勒的《第八交响曲》开头,由乔治·索尔蒂爵士指挥芝加哥交响乐团演奏。

这首交响曲可能与刚才的《Code Monkey》形成鲜明对比。它有时被称为“千人交响曲”,因为需要舞台上庞大的阵容来演奏:一整个交响乐团和一整个合唱团。演奏这首作品需要许多复杂的、协同运作的部分,但它却经常被演奏,并且人们一听就能辨认出来,因为每次演奏都大致相同。

这是如何实现的?世界各地的管弦乐团和合唱团如何能演奏这首极其复杂的作品,并总是呈现出大致相同的结果?同样地,你如何能听完Jonathan Colton的歌,然后作为一名训练有素的音乐家,就能把它学会并自己演奏?

这实际上就是关于可重复性


在音乐中,一个很好的地方在于,当你聆听一场演出时——无论是一首简单的流行歌曲还是一部宏大的交响曲——你获得了所需的所有信息。当然,根据音乐的复杂程度,你接收到的信息量可能不同,因为大脑一次只能处理这么多信息。

但对于像交响曲这样非常复杂的作品,我们实际上有一种方法来写下指令,交给表演者,告诉他们如何演奏每一个部分。马勒本人就是一位指挥家,他知道指挥家常常难以仅凭作曲家的乐谱就完全理解其确切意图。因此,他在创作音乐时,在乐谱的每一寸都标注了指示。这样,诠释音乐的指挥家和演奏者就能明白:“哦,作曲家在这里想要的是这个效果。”

对于马勒的《第八交响曲》,我们拥有总谱。总谱基本上是一本书,列出了每种乐器的每个声部需要演奏的内容以及他们得到的指示。指挥家可以看着总谱说:“好的,我知道小提琴这时在演奏什么,我知道长笛在演奏什么,我知道合唱团在唱什么。”这样,音乐就能被协调、演奏并同步起来。

流行歌曲也可以有乐谱。《Code Monkey》也可以有乐谱,上面会有吉他谱线、鼓谱线。虽然其记谱方式与交响乐总谱不同,但确实存在一种有时用于传达音乐应如何演奏的记谱法。


我们在本课程中讨论的可重复研究,基本上就是:你如何为数据分析创作“乐谱”,以便向他人传达做了什么,以及如果他们想重现这项工作,该如何进行。

数据分析的根本问题在于,我们并没有一个公认的、用于传达数据分析过程的记谱系统。因此,每个人的做法都不同,总体来看,这有点混乱。

  • 有些人只用文字描述做了什么。在某些情况下,这足够了,但在许多情况下并不够。
  • 有些人会提供计算机代码、数据以及所需的一切。有时这很好,但有时又极其复杂,难以梳理。

传达数据分析有多种方式,但我们尚未就一种对所有人(或大致对所有人)都足够有效的方式达成共识。


因此,在本课程中,我们将重点学习如何通过编写动态文档和共享数据,来使用代码传达数据分析过程,以便他人能够重现你所做的工作。

这对于所有数据分析都至关重要,不仅仅局限于狭义的研究。因为如果你想向他人传达你所做的事情,你需要能够提供材料,让他们能够“演奏”——也就是自己进行分析。


本节课我们一起学习了可重复研究的基本理念。我们通过音乐的类比,理解了为复杂过程创建清晰“指令”(乐谱)的重要性。在数据分析中,缺乏统一的“记谱法”导致了沟通和重现的困难。本课程的目标,就是学习如何使用代码、动态文档和数据共享,来为我们的数据分析创作清晰、可执行的“乐谱”,从而实现研究的可重复性,并促进有效的协作与交流。

在本节课中,我们将学习可重复研究的基本概念与核心理念。我们将探讨为什么在科学研究中,复制是验证发现的金标准,以及当完全复制研究面临挑战时,可重复性如何作为一种重要的中间标准出现。课程将解释驱动可重复研究需求的技术趋势,并通过一个空气污染与健康研究的实例来说明其重要性。


在科学领域,复制是验证和确认科学家发现的最重要环节。其基本理念是:如果你声称X导致Y,或维生素C改善疾病,那么独立于原始研究人员的其他科学家会尝试调查同一个问题,看是否能得出相同的结果。如果许多不同的人都得出相同结果并复制了原始发现,那么我们就有理由认为原始发现可能是真实的,这是一个真实的关系或发现。

因此,强化科学证据的终极标准是复制。其目标是让独立的研究人员使用不同的数据不同的方法在不同的实验室进行独立研究,看是否能得到相同的结果。如果一个发现能经受住所有这些不同条件的考验,那么它就更可能是真实的,支持它的证据也就更强。

复制在那些具有重大政策影响或影响监管决策的研究中尤为重要。

复制本身没有问题。这是科学数百年来一直在做的事情,今天也没有错。但问题是,进行复制或复制其他研究正变得越来越具有挑战性。

部分原因在于研究规模越来越大。进行大规模研究需要大量资金。如果你想对同一项研究进行10次复制,就需要10倍的资金,而现在的资金并不像过去那样充裕。有时,复制研究很困难,因为如果原始研究花了20年时间,就很难再等20年来进行复制。有些研究本身就是独一无二的,例如观察特定时间点的独特情况或独特人群,你无法轻易复制那种情境。

因此,存在许多无法复制研究的合理原因。那么问题是,如果无法复制,替代方案就是什么都不做,让那项研究独自成立吗?

可重复研究的理念,就是建立一种最低标准或中间地带。我们虽然不复制整个研究,但也许可以做些介于两者之间的事情。

基本问题是:一方面有黄金标准——复制,另一方面有最差的标准——不作为。那么,我们能在黄金标准和“不作为”之间做些什么呢?这就是我们所思考的可重复性。它帮助我们弥合复制与“不作为”之间的鸿沟。

这个中间地带的基本理念是:你公开原始研究的数据,并公开计算方法,以便其他人可以查看你的数据,运行你所做的分析,并得出与你相同的发现。因此,可重复研究在很大程度上是关于数据分析的验证

因为你并非使用独立的方法收集独立的数据,所以验证你所提出的问题本身会稍微困难一些。但如果你能获取某人的数据和代码(因为分析很可能是在计算机上使用某种编程语言如R完成的),并重现他们得出的发现,那么你至少可以确信分析是恰当进行的,并且使用了正确的方法。

那么,是什么驱动了对这种介于复制和“不作为”之间的可重复性中间地带的需求呢?

在许多不同领域,包括生物学、化学、环境科学等,出现了大量新技术。这些技术使我们能够以更高的通量收集数据,从而几乎即时地获得非常复杂且高维度的数据集,这与仅仅10年前相比都是巨大的进步。技术使我们能够通过按下一个按钮就创建庞大的数据集。

此外,计算能力使我们能够将现有的数据库合并成更大、更大的数据库。我们可以获取以前可能无法访问的数据,并从中创建新的数据集。这些新数据集现在非常庞大。

除了允许我们创建新的数据集,计算能力还使我们能够进行更复杂的分析。我们拟合的模型和编写的算法本身比过去要复杂得多。即使是经验丰富的人,要基本理解这些算法也很困难。因此,理解某人在数据分析中做了什么,需要查看代码,查看人们使用的计算机程序。

所有这些不同趋势的最终结果是:对于每个领域X,现在都有一个计算X,比如计算生物学、计算天文学等等。

以下是我所进行的研究领域中的一个例子:空气污染与健康。这是一个庞大的领域,它汇集了使可重复性在该领域变得非常重要的几个特点。

首先,我们在存在更强信号的情况下,估计非常微小但非常重要的公共卫生效应。你可以将空气污染视为可能有害的东西,但即使它有害,还有许多其他更值得你担忧的有害因素。因此,污染不会是对你危害最大的因素。

其次,许多空气污染研究的结果以及实质性的政策决策、法规都将基于该领域的科学研究。这些法规可能影响许多利益相关者,并且实施起来可能耗资数十亿美元。

最后,我们使用许多复杂的统计方法来进行这些研究,而这些统计方法受到严格的审查。

因此,固有的微弱信号巨大的影响复杂的统计方法这三者的结合,几乎要求我们所做的研究必须是可重复的。

为此,我们在约翰霍普金斯大学创建了“基于互联网的健康与空气污染监测系统”。我们公开了大量数据,并以代码形式公开了许多统计方法,以便他人审查。我们所做的分析和产生的许多结果,都可以被他人重现。


本节课中,我们一起学习了可重复研究的基本概念。我们了解到复制是科学验证的黄金标准,但由于资金、时间、研究独特性等挑战,完全复制有时并不可行。因此,可重复研究作为一种重要的中间标准应运而生,它通过公开数据分析代码,允许他人验证数据分析过程,从而增强科学发现的可靠性和透明度。我们还探讨了大数据和复杂计算分析如何驱动了对可重复性的需求,并通过空气污染研究的实例,看到了可重复性在具有重大公共政策影响的研究中的关键作用。

在本节课中,我们将深入探讨可重复研究的基本概念、其重要性以及实现可重复性所需的关键要素。我们将了解研究流程中作者与读者的互动,分析当前面临的挑战,并明确可重复研究的核心组成部分。


上一节我们介绍了可重复研究的基本背景,本节中我们来看看研究的具体流程以及可重复性在其中扮演的角色。

当你阅读文献中的研究文章时,你通常只能看到最终的论文。然而,在这篇文章背后,存在一个完整的“研究流程”。作者沿着这个流程从左向右推进工作,而读者则试图从右向左追溯,通过文章去了解数据来源和分析过程。

可重复研究的基本理念,就是聚焦于“分析数据”和“计算结果”这两个核心环节。其目标是让作者和读者能在中间环节“相遇”,即读者能够基于作者提供的材料,重现其分析过程与结果。


可重复性在媒体和科学文献中引发了广泛讨论。例如,《科学》杂志曾出版关于数据复现的专刊,电视节目《60分钟》也曾报道杜克大学因多项研究结果无法复现而引发的争议事件,这直接导致多项临床试验中止,并引发了持续调查。

作为回应,美国医学研究所针对此类事件发布了一份报告,旨在为促进和鼓励可重复研究(尤其是在基因组学、蛋白质组学等组学领域)制定**实践标准。这份报告非常重要,其中包含多项关键建议。

以下是该报告的部分核心建议:

  • 数据与元数据应公开可用。
  • 计算机代码应完全公开,以便他人审查分析过程。
  • 计算分析的所有步骤都应被详细描述,使他人能够研究和复现。

那么,实现可重复研究具体需要什么呢?首先,我们需要一个明确的定义。

一个基本的定义包含以下几个关键组成部分:

  1. 可用的分析数据:即研究中实际用于分析并呈现结果的数据。这通常不同于原始数据,因为分析可能只使用了原始数据的一个子集。虽然原始数据可能具有参考价值,但分析数据是检验数据分析的核心。
  2. 可用的分析代码:这是应用于分析数据并产生关键结果的代码,例如回归建模代码等。
  3. 代码与数据的文档:对代码和数据进行充分的说明至关重要。
  4. 标准的传播方式:所有数据和代码必须能够被轻松获取。

用公式来概括,可重复研究 ≈ 分析数据 + 分析代码 + 文档 + 可访问的传播渠道


在讨论可重复性时,涉及多个利益相关方,他们各有不同的需求和挑战。

大致可以分为两类:

  • 作者:他们生产研究,并希望使其工作可重复,因此需要工具来简化这一过程。
  • 读者:他们阅读研究,并希望复现该工作,同样需要工具来降低复现难度。

当前面临的主要挑战包括:

  • 作者需要付出相当大的努力才能在网络上公开其数据和代码,这并非一项简单的任务。
  • 即使材料已公开,读者也需要手动下载数据、代码和结果,并费力地将它们拼凑起来,这个过程通常很繁琐。
  • 读者可能不具备与原作者相同的计算资源(例如大型计算集群),因此难以完全复现相同结果。
  • 尽管正在增长,但用于进行可重复研究的工具箱仍然有限。

现实中,作者可能只是将材料随意发布在网上,或依赖于著名的杂乱无章的期刊补充材料。仅有少数中心数据库可供作者发布数据。如果你的研究领域有一个公认的核心数据库,那很幸运;否则,情况会困难得多。而读者最终往往只能手动下载和组装代码与数据,整合软件环境也可能非常困难。


本节课中,我们一起学习了可重复研究在研究流程中的定位,了解了其受到广泛关注的原因及相关权威建议。我们明确了构成可重复研究的四个核心要素:分析数据分析代码完备文档标准传播。同时,我们也认识到,无论是作者还是读者,在实现和验证可重复性时都面临着工具、资源和流程上的诸多现实挑战。理解这些概念和挑战是迈向更好研究实践的第一步。

在本节课中,我们将学习一种使研究更易复现的基本工具——文学化统计编程。我们将了解其核心概念、历史背景,以及现代工具如何改进这一理念。


上一节我们讨论了数据与代码管理的重要性。本节中,我们来看看如何将分析与文档自然地结合起来。

文学化统计编程源于计算机科学中的“文学化编程”思想。其核心是将一篇文章、出版物或报告视为文本流与代码流的结合体。

  • 文本部分:供人阅读,解释分析的背景、步骤与结果。
  • 代码部分:供计算机执行,用于加载数据、计算和生成结果。

分析过程由一系列文本块代码块共同描述。代码块执行具体操作(如计算),文本块则以人类可读的语言阐述上下文。其中可能包含用于格式化表格和图形的呈现代码,以及解释代码逻辑的文章文本。这种文本与代码的混合体,就构成了一个文学化统计程序文学化统计分析

这些程序可以通过“编织”生成人类可读的文档(如PDF或HTML网页),也可以通过“缠绕”生成机器可读的代码文档。

文学化编程的基本思想是,你需要一种人类可读的文档语言和一种机器可读的编程语言


在R语言中,实现这一理念的原始系统叫做 Sweave。它由R核心成员Friedrich Leisch开发,目前仍由R核心团队维护。

Sweave的结构如下:

  • 文档语言:LaTeX
  • 编程语言:R

然而,原始的Sweave系统存在许多局限:

  • 学习曲线陡峭:它主要依赖LaTeX,这是一种许多人并不熟悉的标记语言。
  • 功能有限:缺乏缓存、每页多图、混合编程语言等现代需求的功能。
  • 开发活跃度低:更新和维护不够频繁。

近年来,一个重要的替代工具出现了,那就是 knitr 包。它由谢益辉在爱荷华州立大学攻读研究生时开发,现已成为一个非常流行的文学化统计编程工具。

knitr在Sweave原始概念的基础上进行了大量改进和功能增强:

  • 灵活的编程语言:虽然仍以R为主要语言,但允许混合使用其他编程语言。
  • 多样的文档语言:不仅支持LaTeX,还支持更易上手的 MarkdownHTML

这使得创建可重复文档的门槛大大降低,功能也更加丰富。


本节课我们一起学习了可重复研究的核心实践工具——文学化统计编程。

总结来说,对于计算密集型的分析,可重复研究是一项重要的最低标准,尤其是在复制研究非常困难甚至不可能的情况下。虽然我们仍需要更多的基础设施和工具来创建和分发可重复文档,但这一领域每天都在进步,新工具不断涌现。

在下一讲中,我将详细介绍一些这样的工具,特别是 knitr,并向大家展示如何用它来生成可重复的研究文档。

在本节课中,我们将探讨如何通过脚本化你的分析工作来确保其可重复性。我们将从核心原则开始,解释为什么脚本化至关重要,并通过一个生动的类比帮助你理解其价值。最后,我们将介绍如何开始编写你的第一个脚本。

在深入探讨各种工具和技术之前,我们首先需要明确贯穿整个课程的基本原则。我认为,如果你想尽可能地使你的工作可重复,有一条最重要的规则需要遵守:你应该将一切都脚本化

脚本化非常重要,其基本理念是将所有事情都记录下来。在过去,你可能需要将事情写在纸上或实验笔记本中。但现在,我们拥有更精密的计算机,并且可以对其进行编程,因此你可以将事情写成脚本或程序。

为了帮助你理解,我们可以做一个类比。想象一首伟大的交响乐或音乐作品。如果你只听到一段旋律,那会很有趣,也可能非常优美。但通常,一部交响乐背后有整个管弦乐队和一系列音乐家在支撑着旋律,完成大量工作。所有这些工作都非常重要,它们构成了音乐的质感和整体感觉。

如果你只是听一场交响乐,即使你能雇佣自己的乐队,你也很难重现那个声音。因为你不知道所有音符的位置,也不知道在特定时刻各种乐器在演奏什么。即使你听了几遍,可能仍然无法做到。特别是,如果你只听到旋律,你肯定无法重现那个声音。

将研究或分析报告想象成只听到旋律。旋律本身很好、很重要,但所有幕后的支持材料——你做的所有分析、探索性工作、走过的弯路、在分析中做出的但未在最终论文或口头报告中呈现的所有决定——都非常重要。这些就是“支持者”。

就像在音乐中一样,在研究中,我们需要一种方法来记录我们所做的一切、正在发生的一切。在音乐中,这通常被称为乐谱。乐谱是一种用音乐符号记录所有正在演奏的不同内容、所有音符、节奏、时间、乐器等一切的方式。这样,有人就可以看着乐谱说:“好的,我需要整合所有这些内容,人们需要在不同的时间、不同的位置进行演奏。” 这是一种尽可能准确地重现一首音乐作品的方式。音乐家们已经就记录音乐的标准方式和标准符号达成了一致。

本课程本质上就是关于定义和开发用于指定研究项目或数据分析的“符号”。我们如何记录我们所做的事情?我们如何准确地讨论分析了什么、做了什么?我们实现这一点的基本方式就是通过脚本化

我们编写计算机程序,向计算机发出指令,告诉它在任何给定时间对什么类型的数据做什么。因此,对于你在数据分析中所做的任何事情,主要规则就是编写一个脚本。你越多地这样做,越少地手动操作而不做记录,你的工作就会越好、越可重复。

我们编写的这些计算机程序、这些脚本,就像是你的数据分析的乐谱。它们告诉试图重现你工作的其他人,到底发生了什么以及该做什么。

如果你想了解脚本化某事的含义,可以打开RStudio。当你打开它时,你会看到首先可以做的就是打开一个R脚本。我们在这里操作,这只是一个空白的文本文件。然后你可以开始在这里编写R代码,你将进行编程,用编码语言告诉R该做什么。这是开始脚本化最简单的方式:加载像RStudio这样的工具,并使用其内置的文本编辑器。

在本课程中,我们将讨论一系列其他工具,比如knitr、Markdown,它们将帮助你组织分析。但归根结底,核心是记录下来:编写脚本,编写程序,让你的工作可重复。

本节课中,我们一起学习了可重复研究的核心理念:脚本化一切。我们通过音乐与乐谱的类比,理解了脚本作为数据分析“乐谱”的重要性,它完整记录了分析过程的所有细节,使他人的复现成为可能。最后,我们了解了使用RStudio等工具开始编写脚本的基本步骤。记住,将你的分析过程转化为代码脚本,是迈向严谨、可重复科学研究的关键一步。

在本节课中,我们将学习数据分析的基本流程与结构。虽然并非所有分析都完全相同,但了解其核心组成部分及其如何衔接,能为理解数据分析提供一个有用的模板。

如果列出数据分析的步骤,可能会得到类似以下列表的内容。大多数分析都包含这些步骤的一个子集。在本讲(第一部分)中,我们将讨论:定义问题、确定理想数据集、确定可获取的数据、获取数据以及清理数据。在第二部分,我们将讨论剩余的主题。

以下是数据分析的典型步骤列表:

  • 定义问题
  • 确定理想数据集
  • 确定可获取的数据
  • 获取数据
  • 清理数据
  • 探索性数据分析
  • 统计预测/建模
  • 解释结果
  • 挑战结果
  • 综合撰写报告
  • 创建可重复的代码

数据分析的一个关键挑战,被数学教育家丹·迈耶在其TED演讲中很好地概括了。他问道:你曾解决过哪个值得解决的问题,是事先知道所有给定信息的?要么是信息过剩需要筛选,要么是信息不足需要寻找。这正是数据分析的关键:通常你并非掌握所有事实,就是信息过多需要梳理。数据分析的很大一部分过程,就是整理所有这些信息。


数据分析首先要从定义问题开始。并非所有分析都始于一个非常具体或连贯的问题,但你在提出合理问题上投入的努力越多,后续筛选大量信息所需的工作就越少。原因是,定义问题是你所能使用的最强大的降维工具。例如,如果你只关心身高或体重等特定变量,就可以排除许多与此无关的其他变量。因此,尽可能具体地缩小问题范围,将有助于减少处理潜在庞大数据集时需要应对的“噪音”。

有时你只是想查看数据、探索其中的内容,那就需要检查大型数据中的各种信息。但如果你能将兴趣范围缩小到特定类型的问题,这对简化问题将极为有用。因此,建议在深入研究数据细节之前,先思考你想回答什么类型的问题。

一般来说,科学背景决定了你感兴趣的问题类型,这引导你找到数据,进而应用应用统计学来分析数据。如果你更有雄心,可能会思考一些理论统计学,以将你应用的方法推广到不同类型的数据。当然,能做到这一点的人相对较少,因此并非对每个人的要求。

图中红色括号内的部分(第1点)通常被称为统计方法开发。而紫色括号内的部分(第2点),即在没有科学背景的情况下将统计学直接应用于原始数据,我称之为“危险区”。这个想法源自德鲁·康威绘制的数据科学维恩图。其核心是,如果你只是随机地将统计方法应用于数据集以寻找有趣的答案,你几乎肯定会发现一些有趣的东西,但它可能不可重复,也可能没有真正意义。因此,一个真正恰当的数据分析应具有科学背景,最好至少有一个我们试图研究的总体问题,这将缩小问题的维度,然后我们将适当的统计方法应用于适当的数据。


让我们从一个非常基本的问题例子开始。一个普遍性问题可能是:我能自动检测电子邮件是垃圾邮件还是非垃圾邮件吗? 当然,如果你使用电子邮件,这是一个重要问题,你想知道哪些是应该阅读的重要邮件,哪些只是垃圾邮件。

如果你想将其转化为数据分析问题,有多种方式可以回答。例如,你可以雇人手动检查邮件并判断是否为垃圾邮件,但这可能不可持续,效率也不高。因此,要将其转化为数据分析问题,你需要让问题更具体,并使用数据分析工具特有的术语来转化它。

一个更具体的版本可能是:我能使用电子邮件本身的定量特征将其分类为垃圾邮件(spam)或正常邮件(ham)吗? 现在,我们可以开始查看邮件,并思考:为了对邮件进行分类,我需要开发哪些定量特征?


一旦有了问题,我们想知道:如何区分邮件以识别垃圾邮件?这样,你或许就能过滤掉所有垃圾邮件,只阅读真正的邮件。

首先要思考的是:针对这个问题,理想的数据集是什么? 如果我拥有世界上所有的资源,我会去寻找什么?根据目标和所提问题的类型,你可以收集不同类型的数据集。

以下是不同类型问题对应的理想数据集:

  • 描述性问题:可能需要整个总体的数据(例如,进行一次普查)。
  • 探索性问题:可能只需要一个包含许多测量变量的随机样本
  • 推断性问题:必须非常小心抽样机制和所抽样的总体定义,因为你是从样本中得出结论来推断更大的总体。
  • 预测性问题:需要来自你感兴趣总体的训练集测试数据集,以便构建模型和分类器。
  • 因果性问题:需要实验数据,例如来自随机试验或随机研究的数据。
  • 机制性问题:需要关于你所描述系统的所有不同组成部分的数据。

对于我们的垃圾邮件问题,一个理想的数据集或许是:如果你使用Gmail,你知道所有邮件都存储在谷歌的数据中心。那么,我们何不获取谷歌数据中心的所有数据呢?因为那将是邮件的整个总体,我们可以基于所有这些数据构建分类器,而无需担心抽样问题。这将是一种理想的数据。


当然,在现实世界中,你必须思考:你实际上能获取哪些数据? 也许谷歌内部有人能访问所有通过Gmail的邮件,但即使在这种极端情况下也可能很困难,而且大多数人无法获取这些数据。因此,有时你不得不退而求其次,选择不那么理想的数据。

你可能需要在网络上寻找免费数据,或从提供商处购买数据。在这些情况下,务必尊重数据的使用条款。任何你同意的关于数据的协议或合同都必须遵守。如果数据根本不存在,你可能需要自己以某种方式生成数据。

获取谷歌的所有数据很可能不可行,因为他们的数据中心安全级别非常高。因此,我们必须寻找其他方案。


一个可能的解决方案来自UCI机器学习库中的垃圾邮件数据集。这个数据集由惠普公司的人员创建,他们收集了几千封垃圾邮件和正常邮件,并进行了适当分类。你可以使用这个数据库来探索如何将电子邮件分类为垃圾邮件或正常邮件的问题。

获取数据时,首要目标是尝试获取原始数据(例如从UCI机器学习库获取)。必须小心注明来源。无论从哪里获取数据,都应始终注明来源并记录其出处。

如果你需要向不熟悉的研究者索要数据,一封非常礼貌的电子邮件通常大有帮助,他们可能愿意与你分享数据。如果从互联网来源获取数据,至少应记录URL(获取数据的网站地址)以及访问的日期和时间,以便将来他人有据可查。网站可能会关闭,URL可能会改变或无法访问,但至少在你获取数据时,你记录了获取方式。

在本例中,既然我们无法访问谷歌数据中心,我们将讨论的数据集就是这个垃圾邮件数据集,你可以从R语言的kernlab包中获取。安装该包后,即可直接加载数据。


对于任何数据集,你通常需要做的第一件事就是进行一些清理。原始数据通常需要经过某种处理,才能变成可以建模或输入建模程序的形式。

如果数据已经过预处理,重要的是了解它是如何被预处理的。尝试获取有关预处理内容及方式的文档。你需要了解数据的来源,例如,它是否来自调查?抽样是如何进行的?是方便抽样吗?数据来自观察性研究还是实验?数据的来源非常重要。

你可能需要以特定方式重新格式化数据,以便其适用于特定类型的分析。如果数据量极大,你可能希望对数据进行二次抽样,使其更易于管理。

记录所有清理步骤至关重要。你应该将这些步骤写在脚本或最方便的地方,因为无论是你自己还是他人,如果想要复现你的发现,都需要重复这些步骤。如果你不记录所有这些预处理步骤,那么将无人能够再次完成。

一旦清理完数据并对其有了基本了解,重要的是判断数据是否足以解决你的问题。因为在某些情况下,数据可能不够好:数据量可能不足,变量或特征可能不够,数据的抽样方式可能不适合你的问题。在清理数据的过程中,你可能会意识到各种问题。

如果你确定数据不足以解决你的问题,那么就应该停止,尝试重新获取数据、更换数据或改变问题。重要的是,不要仅仅因为你手头只有这些数据就强行继续分析,这可能导致不恰当的推断或结论。


以下是我们将在本例中使用的已清理数据集(它已在kernlab包中为我们清理好)。这里只展示了前五个变量,数据中还有许多其他变量。你可以看到,共有4601个观测值和5个变量(此处显示)。我已将链接放在这里,你可以查看帮助页面,了解数据集的来源和处理方式。


在本节课的第一部分,我们一起学习了数据分析流程的前半部分核心步骤。我们从定义具体、可分析的科学问题开始,这是最有效的降维工具。接着,我们探讨了如何根据问题类型(描述、探索、推断、预测、因果、机制)来确定理想的数据集。然后,我们面对现实,讨论了如何评估和获取实际可用的数据,并强调了记录来源和遵守条款的重要性。最后,我们深入了数据清理环节,包括理解预处理、格式化数据、子抽样,并特别强调了详细记录所有清理步骤对于确保分析可重复性的关键作用。

记住,清晰的问题定义和严谨的数据获取与清理,是构建可靠、可重复数据分析的坚实基础。在下一部分,我们将继续探讨数据分析的后续步骤。

在本节课中,我们将继续学习数据分析的完整流程。上一节我们介绍了数据分析的前半部分步骤,本节我们将探讨剩余的关键环节,包括探索性数据分析、统计建模、结果解释与挑战、成果综合与撰写,以及如何创建可重复的代码。

上一节我们介绍了数据准备和问题定义。本节中,我们来看看如何通过探索性数据分析来初步了解数据。

我们的目标是:能否根据电子邮件的量化特征,自动将其分类为垃圾邮件(spam)或正常邮件(ham)?我们使用的数据集来自UCI机器学习仓库,包含4600个观测值(邮件)和58个不同的变量(特征)。

首先,我们需要将数据集分割为训练集和测试集。我们使用训练集构建模型,使用独立的测试集评估模型性能。以下代码通过随机抽样将数据分为两半:

set.seed(123) # 设置随机种子以确保结果可重复 split <- rbinom(nrow(data), 1, 0.5) training_set <- data[split == 1, ] test_set <- data[split == 0, ] 

以下是探索性数据分析的几个关键步骤:

  • 查看基本摘要:检查数据的维度、变量类型和基本统计量。
  • 检查缺失数据:确认数据集中是否存在缺失值,并思考其原因。
  • 创建探索性图表:通过可视化了解单个变量的分布以及变量之间的关系。

例如,我们可以比较垃圾邮件和正常邮件中“大写字母平均数量”这个变量的分布。由于数据高度偏斜,我们通常查看其对数变换后的结果(为避免对0取对数,先给变量值加1):

# 绘制对数变换后的分布图 library(ggplot2) data$log_capital_avg <- log10(data$capital_avg + 1) ggplot(data, aes(x=type, y=log_capital_avg)) + geom_boxplot() 

图表显示,垃圾邮件通常含有更多的大写字母。我们还可以通过聚类分析探索预测变量之间的关系。对预测变量进行对数变换后,层次聚类的结果显示,“capitalAverage”自成一类,而“you”、“will”、“your”等词则聚集在另一类中。

完成数据探索后,我们可以开始构建统计模型。建模方法取决于具体的研究问题,并应参考探索性分析的结果,同时考虑数据是否经过处理或变换。

在本例中,我们将尝试一个基础的建模方法:为数据集中的每一个预测变量单独拟合一个逻辑回归模型,看看仅凭一个变量能多好地预测邮件是否为垃圾邮件。

以下是实现这一过程的代码框架:

# 初始化一个向量来存储交叉验证误差 cv_errors <- numeric(ncol(training_set) - 1) # 假设最后一列是响应变量‘type’ predictor_names <- names(training_set)[-ncol(training_set)] ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/547c5a2fbfe9e83dc1515de17539f994_15.png) for (i in seq_along(predictor_names)) # 找出误差最小的预测变量 best_predictor <- predictor_names[which.min(cv_errors)] 

运行后发现,单个预测变量中交叉验证误差最小的是 char_dollar(邮件中美元符号的数量)。我们使用这个“**”变量重新拟合一个逻辑回归模型。

模型拟合后,我们需要解释结果并在测试集上评估其性能。

首先,使用拟合好的模型对测试集进行预测。逻辑回归输出的是邮件为垃圾邮件的概率(介于0和1之间)。我们设定一个阈值(例如0.5)将连续概率转化为分类:

# 使用**预测变量拟合最终模型 final_model <- glm(type ~ char_dollar, data=training_set, family="binomial") # 在测试集上进行预测 test_predictions_prob <- predict(final_model, newdata=test_set, type="response") test_predictions_class <- ifelse(test_predictions_prob > 0.5, "spam", "ham") 

接着,将预测分类与测试集中的真实标签进行比较,生成混淆矩阵并计算错误率:

# 创建混淆矩阵 confusion_matrix <- table(Predicted = test_predictions_class, Actual = test_set$type) print(confusion_matrix) # 计算错误率 error_rate <- (confusion_matrix[1,2] + confusion_matrix[2,1]) / sum(confusion_matrix) cat("测试集错误率:", round(error_rate * 100, 1), "%") 

在我们的示例中,模型在测试集上的错误率约为22.4%,即准确率为77.6%。

在得出最终结论前,主动挑战自己的分析过程和结果至关重要。这能让你提前应对他人可能提出的质疑。

需要审视的方面包括:

  • 问题本身:这是否是一个有效的问题?
  • 数据来源与处理:数据从何而来?清洗和处理过程是否合理?
  • 分析方法:为什么选择这个模型?它是否是**或最合适的?如何选择纳入模型的变量?
  • 不确定性度量:使用的不确定性度量(如误差率)是否恰当?
  • 替代分析:是否有其他分析方法可能更有效或提供不同视角?

分析完成后,需要将结果综合并撰写成文或进行演示。综合意味着从众多分析中提炼出最重要的部分,讲述一个连贯的故事。

讲述故事的典型结构是:

  1. 引出问题:首先明确要解决的核心问题。
  2. 交代背景与方法:说明使用了什么数据,以及为什么采用当前的分析方法。
  3. 总结关键分析:按逻辑顺序呈现支持结论的关键分析,而非按执行的时间顺序。
  4. 展示核心结果:使用精心设计的图表清晰展示主要发现。
  5. 给出解释与结论:解释结果的含义,并指出其合理性与局限性。

在我们的例子中,故事线可以是:为了根据量化特征分类垃圾邮件,我们使用了UCI的邮件数据集,通过探索发现美元符号数量与垃圾邮件高度相关;基于此建立的单变量逻辑回归模型在测试集上达到了77.6%的准确率;这个结果直观上合理(垃圾邮件常包含更多美元符号),但准确率仍有很大提升空间,未来可考虑纳入更多变量或使用更复杂的模型。

最后,也是贯穿始终的一点,是确保你的分析是可重复的。这意味着你或他人在未来能够准确地复现整个分析过程。

实现可重复研究的关键是:

  • 使用脚本语言:如R、Python,所有操作都应记录在脚本中。
  • 利用文档化工具:例如在R中,可以使用 R Markdownknitr 包。它们允许你将代码、结果(图表、表格)和文字叙述整合在同一个动态文档中。
  • 保持组织有序:清晰地组织项目文件夹,区分数据、代码和结果。
  • 记录会话信息:使用 sessionInfo()(R)或类似命令记录软件包版本,这对于重现计算环境非常重要。

一个简单的R Markdown文档结构如下:

r
---
title: "垃圾邮件预测分析"
author: "你的名字"
date: "`r Sys.Date()`"
output: html_document
---
 概述
本次分析旨在...
 数据准备
{r data-prep}
# 加载和分割数据的代码

 探索性数据分析
{r eda}
# 绘制图表和摘要的代码

 建模与预测
{r model}
# 建模和评估的代码


通过这样的方式,你的整个分析流程就变得透明、可追溯且易于他人验证,从而极大地增强了研究结论的说服力。

本节课中,我们一起学习了数据分析流程的后半部分。我们从探索性数据分析入手,初步了解了数据特征;随后建立了一个简单的统计预测模型(逻辑回归)并评估其性能;接着我们强调了在解释结果后,必须主动挑战自己的分析;然后,我们探讨了如何将复杂的分析过程综合成一个连贯的故事进行呈现;最后,我们指出了使用像R Markdown这样的工具来创建可重复、可文档化的分析代码的重要性。掌握这个完整的流程,是进行严谨、可信的数据分析的关键。

在本节课中,我们将学习如何有效地组织一个数据分析项目。虽然不存在适用于所有人和所有项目的通用方法,但掌握一些基本原则和实用技巧,可以帮助你将项目文件有条理地放置,并最终确保你的分析工作对你或他人而言都是可重复的。


一个完整的数据分析项目通常会包含多种类型的文件。理解这些文件的角色和关系,是组织项目的第一步。

以下是你在一个主要项目中可能会保留的关键文件类型:

  • 数据文件:包括原始数据和经过处理的数据。
  • 图表与表格:分为探索性图表和最终图表。
  • 代码文件:包括原始的、未使用的脚本和最终的分析脚本。
  • R Markdown文件:用于生成可重复的报告。
  • 文本文件:如说明文档和最终的报告或论文。

所有这些元素——数据、图表、表格和代码——最终都需要通过文本来整合,讲述一个完整的数据分析故事。


上一节我们概述了项目中的各类文件,本节我们来详细看看数据文件。

原始数据可能以多种形式存在,例如文本记录或特定格式的文件。你需要对这些数据进行处理,使其能被分析程序(如R)使用。例如,进行文本解析或格式转换。

存储原始数据时,务必记录其来源和获取信息,这对于可重复性至关重要。建议将这些信息记录在README文件中,或如果使用Git等版本控制系统,可以在提交日志中注明。

记录信息应包括

  • 数据集的来源网址(URL)
  • 数据集的简要描述
  • 访问或下载数据的日期

处理后的数据通常比原始数据更整洁,常以表格形式存储,包含行和列。

处理数据应遵循以下原则

  1. 文件命名清晰:通过文件名就能看出是由哪个脚本生成的。
  2. 记录处理脚本:在文档中明确说明是哪个代码文件将原始数据转换成了处理数据。
  3. 保持数据“整洁”:处理后的数据应是规整的,以便直接用于后续的建模或分析函数。一个“整洁”的数据集通常满足:每个变量一列,每个观测一行。

在数据处理之后,我们通常通过可视化来理解数据。根据目的不同,图表可分为探索性和最终两种。

探索性图表是你在分析过程中为初步查看数据而制作的。数据通常是高维的,因此你需要从不同角度、分批次地观察数据。

探索性图表的特点

  • 目的:快速了解数据的各个方面。
  • 外观:无需精美,但需清晰可辨,便于理解。
  • 数量:会制作很多,但大部分不会进入最终报告。

最终图表是用于报告或论文的成品,它们更加精炼和美观。

最终图表的特点

  • 目的:清晰、有力地传达核心发现。
  • 外观:组织良好,标注清晰,可读性强(例如,可能使用多面板图来整合信息)。
  • 数量:数量很少,是海量探索性图表中的精华。通常一篇论文只有4-5个图,以避免信息过载。

图表源于代码,而代码本身也需要良好的组织。在分析过程中,你会产生大量代码文件。

这些脚本是分析过程中的“草稿”,可能用于尝试性分析或生成探索性图表。

它们的特点

  • 注释较少,结构可能随意。
  • 可能存在多个版本。
  • 包含了许多最终被弃用的分析路径。

这些是构成最终分析的“终稿”代码。

它们的特点

  • 注释清晰:包含大段的章节说明和解释具体步骤的小注释。
  • 结构完整:包含从原始数据处理到模型拟合、图表生成的全链条代码。
  • 可追溯:他人看到最终报告时,应能明确知道是哪些脚本生成了它。

组织建议:将最终脚本与未使用的脚本分开存放,例如放在不同的项目子目录中,但保留未使用的脚本以备查考。


为了将代码、结果和叙述文本整合在一起,我们需要使用特定的工具。

R Markdown 并非必需,但它极其有用,可以生成可重复的报告

其优势在于

  • 能在同一文档中嵌入代码、文本、图表和结果。
  • 可一键编译生成网页(HTML)、PDF等格式的友好报告。
  • 在RStudio中易于创建和使用,是介于原始代码与精美终稿之间的理想中间产物。

如果你的项目不使用R Markdown,那么README文件就至关重要。它解释了项目目录的结构和内容。

一个良好的README文件应包含

  • 项目概述。
  • 分步指南:说明先运行哪个代码处理数据,再运行哪个代码拟合模型等。
  • 文件组织结构说明。

核心概念:使用R Markdown是“文学化编程”或“文学化统计分析”的实践,它力求将文档、代码和数据集成在单一文件中,而非彼此分离。


所有分析工作的结晶是一份最终的文档或报告,例如一篇论文。

一份标准的研究报告通常包括以下部分

  1. 标题
  2. 引言:阐述研究问题和动机。
  3. 方法:描述所使用的数据和方法。
  4. 结果:呈现主要发现,并报告不确定性度量。
  5. 讨论/结论:总结分析结果,指出局限性或潜在问题。

撰写最终报告的关键

  • 讲述连贯的故事:你需要从所有分析中提炼出一个逻辑清晰、重点突出的叙述,而不是事无巨细地罗列所有尝试。
  • 引用与方法说明:务必引用所使用的统计方法、软件包和具体实现,这对他人的复现至关重要。

以上是组织数据分析的一些基本要点。每个具体项目都有其特殊性,但以下资源可以提供更深入的指导和自动化帮助:

  • 不可重复研究的案例:关于癌症数据分析的不可重复案例研究链接。
  • 可重复研究政策:《生物统计学杂志》上关于可重复研究政策的社论。
  • 项目管理指南:一些关于管理统计分析项目的指南和**实践。
  • ProjectTemplate软件包:一个R包,可以自动化数据分析项目中许多常规的初始化工作,值得尝试。

在本节课中,我们一起学习了如何组织一个可重复的数据分析项目。我们了解了项目中常见的各类文件(原始/处理数据、探索性/最终图表、代码脚本、R Markdown、说明文档和最终报告)及其作用与组织原则。记住,清晰的组织结构、完整的记录和连贯的故事叙述,是确保分析工作对你和他人都具有可重复性的关键。

在本节课中,我们将学习R语言中的编码标准。这些标准能帮助你编写可读性更强的代码,让你和他人更容易理解代码的逻辑和结构。

编码标准对于任何编程语言都至关重要,R语言也不例外。遵循一致的编码规范,不仅能提升代码的可读性,还能促进团队协作和代码维护。本节将介绍几个基础的、被广泛接受的R语言编码原则。

以下是编写R代码时应遵循的几个核心原则。

在任何编程语言中,包括R,都应始终使用文本编辑器编写代码,并将代码保存为文本文件。

文本文件是一种基础标准,通常不包含任何特殊格式或样式。它只是纯文本,通常是ASCII编码。使用文本编辑器是编写代码的“最小公分母”,它能确保任何人都能访问并改进你的代码。

为了提升代码的可读性,缩进是至关重要的。缩进是指将不同的代码块向右移动一定距离,以便通过缩进本身就能看出程序的控制流和结构。

与缩进原则紧密相关的是限制代码的宽度。如果你无限制地向右缩进,代码会变得难以阅读。因此,需要限制代码行的最大宽度,通常以文本列数来衡量。一个常见的做法是将代码宽度限制在80个字符以内。

R语言中的函数理论上可以写得很长,但为了逻辑清晰和易于调试,应该限制每个函数的长度。一个函数最好只完成一项基本活动。

上一节我们介绍了四个基本原则,本节中我们来看看如何具体应用它们,并通过示例加深理解。

缩进量的大小常引发讨论。虽然具体数量可能因人而异,但关键是理解缩进的重要性。缩进过少会使代码挤在一起,难以区分不同的代码块。

以下是一个缩进不佳的代码示例:

# 缩进不佳的示例 my_function <- function(x) else { print("Non-positive") } } 

在RStudio等编辑器中,你可以轻松调整缩进设置。例如,将缩进设置为4个或8个空格,并使用“重新缩进”功能,可以使代码结构一目了然。

# 缩进良好的示例(使用4个空格) my_function <- function(x) else { print("Non-positive") } } 

将缩进设置为8个空格,并配合80字符的右侧边距限制,有一个额外的好处:它会促使你以不同的方式思考代码结构。例如,当嵌套多个for循环时,过深的缩进会很快触及右侧边界,这提示你可能需要将复杂逻辑拆分成独立的函数,从而避免编写难以阅读的深层嵌套代码。

函数应该专注于完成单一、逻辑明确的任务。例如,一个名为read_data的函数应该只负责读取数据,而不应同时处理数据、拟合模型和打印输出。

将代码拆分为逻辑清晰的函数有几个优点:

  • 可读性:单个函数可以完整地显示在一屏编辑器内,便于整体理解。
  • 调试与性能分析:当使用traceback、性能分析器或调试器时,如果函数逻辑划分清晰,这些工具能更精确地指出问题发生在函数调用栈的哪个部分。如果所有逻辑都塞在一个冗长的函数里,调试器只能告诉你这个函数有问题,而难以定位具体位置。

当然,也要避免走向另一个极端,即创建大量只有两三行的微小函数。关键在于确保函数的分离是逻辑上合理的,每个函数都专注于完成一件特定的事情

本节课中我们一起学习了R语言编码的四个核心标准:

  1. 使用文本编辑器编写和保存代码。
  2. 对代码进行缩进(建议至少使用4个空格,个人推荐8个空格以增强结构清晰度)。
  3. 限制代码行的宽度(例如不超过80个字符)。
  4. 限制函数的长度和复杂度,确保每个函数职责单一、逻辑清晰。

遵循这些基本原则,你的R代码将变得更具可读性,无论是对你自己还是对他人而言,都能使代码的编写和维护变得更加高效和实用。

在本节课中,我们将学习Markdown语言的基础知识。Markdown是一种轻量级标记语言,旨在让用户专注于内容创作,而无需处理复杂格式。我们将介绍其核心语法和基本用法。


Markdown是一种面向网络写作者的文本到HTML转换工具。它允许你使用易于阅读和编写的纯文本格式进行写作,然后将其转换为结构上有效的XHTML。其设计理念是让创作者专注于内容本身。

上一节我们介绍了Markdown的基本概念,本节中我们来看看它的核心语法。Markdown的语法设计得非常简洁直观。

以下是基本的文本格式化方法:

  • 使用单个星号包裹文本可以使其变为斜体,例如:*斜体文本*
  • 使用两个星号包裹文本可以使其变为粗体,例如:粗体文本

你可以创建不同层级的标题,类似于HTML中的

标签。

  • 使用一个井号表示一级标题:# 一级标题
  • 使用两个井号表示二级标题: 二级标题
  • 使用三个井号表示三级标题: 三级标题

创建列表是Markdown的常用功能。以下是两种主要列表的创建方式:

  • 无序列表:在每行开头使用连字符(-)、星号(*)或加号(+)即可创建无序列表。符号的选择并不重要,只需在列表中保持一致。
  • 有序列表:在每行开头直接使用数字加句点(例如 1.2.)即可创建有序列表。一个有用的技巧是,你无需按顺序编号,Markdown处理器会自动为你排序。例如,即使你写成 1.4.2.,最终输出也会是正确顺序的列表。

在文档中插入链接非常重要。Markdown提供了两种插入链接的方式:

  1. 内联链接:将链接文本放在方括号[]中,紧接着将URL放在圆括号()里。格式为:[链接文本](URL)。例如:[约翰霍普金斯大学](https://www.jhu.edu)
  2. 引用式链接:为了使行文更整洁,尤其是当URL很长时,可以使用引用式链接。首先,用方括号[]定义链接文本和引用标识,格式为:[链接文本][引用标识]。然后,在文档的其他地方(通常是底部)定义该标识对应的真实URL,格式为:[引用标识]: URL。这种方式将冗长的URL移到了文档末尾,保持了编辑时正文的清晰易读。

在Markdown中创建新行有一个需要注意的细节:在行末添加两个空格,然后按回车键,才会产生一个真正的换行。如果只是简单地按回车键,文本会连接在一起。这是Markdown初学者常会遇到的一个小问题。


本节课我们一起学习了Markdown的基础语法,包括文本格式化、标题、列表、链接和换行的创建方法。

Markdown的官方文档简短易读,你可以在几分钟内掌握它。此外,GitHub在其平台上使用了一种增强版的Markdown(GitHub Flavored Markdown),如果你计划在GitHub上撰写文档,查阅其指南会很有帮助。

总而言之,Markdown以其简洁的语法,让你能够专注于内容创作,并轻松地将文档转换为格式良好的网页,是可重复研究和工作流中非常实用的工具。

在本节课中,我们将学习R Markdown的基本概念。这是一种将R代码与文档撰写相结合的工具,旨在简化数据分析报告的创建过程,并确保代码的可重复性。

上一节我们介绍了本课程的主题,本节中我们来看看R Markdown的基础之一——Markdown语言。

Markdown是一种非常简单的标记语言。它的设计哲学是让作者能够专注于写作内容本身,而不是复杂的格式设置。与HTML、LaTeX或XML等语言相比,Markdown的语法直观且易于学习。

以下是Markdown的一些核心特点:

  • 设计目标:帮助作者专注于内容创作,而非格式。
  • 语法特点:提供基础的、直观的格式化元素,如粗体、章节标题和列表。
  • 灵活性:允许在文档中直接插入任意的HTML元素,以实现更复杂的格式。
  • 可转换性:可以轻松地通过工具链转换为HTML等多种格式。

更多关于Markdown的详细信息,可以参考其创始人John Gruber的网站。

了解了Markdown之后,本节我们来看看R Markdown是什么。

R Markdown本质上是将R代码嵌入到Markdown文档中。其核心思想是,在一个使用Markdown语法书写的文档里,可以包含可执行的R代码块。

  • 一个R Markdown文档看起来像标准的Markdown文档,但其中“点缀”着被称为“代码块”的R代码。
  • 这些代码块由特殊的格式标签标识。
  • 这类文档通常使用 .Rmd 作为文件扩展名。

使用R Markdown的一个主要优点是,它允许你将“活的”R代码插入文档。当处理该文档以生成最终报告(如HTML)时,其中的R代码会被自动执行和评估。这意味着,文档中展示的任何代码,都必须是能够成功运行的,因为生成文档的过程本身就验证了代码的有效性。

因此,R Markdown的基本理念是:你可以执行R代码,并将代码运行的结果(如图表、表格)直接插入到生成的Markdown文档中。它是实现“文学化统计编程”的核心工具,我们将在后续讨论可重复研究时深入探讨。

现在我们知道R Markdown是什么了,本节将介绍处理它的基本工作流程。

你可以使用R中的 knitr 包来处理R Markdown文档。knitr 会读取 .Rmd 文件,执行其中所有的R代码,将结果嵌入,并输出一个纯Markdown文件(.md)。随后,可以使用R的 markdown 包将这个Markdown文件转换为HTML等最终格式。

以下是处理R Markdown文档的关键步骤和工具:

  • 核心工具knitr 包和 markdown 包。
  • 编辑工具:任何基本的文本编辑器都可以用来创建和编辑R Markdown文档,无需复杂的专用软件。
  • 工作流程
    1. 编写核心的 .Rmd 源文件(包含Markdown文本和R代码)。
    2. 使用 knitr 包将 .Rmd 文件转换为 .md 文件。
    3. 使用 markdown 包将 .md 文件转换为最终的 .html 文件。
  • 重要原则:你只编辑最初的 .Rmd 源文件,而不编辑中间生成的 .md 文件或最终的 .html 文件。

如果你使用RStudio,整个过程会变得非常简单。RStudio集成了 knitrmarkdown 的功能,甚至内置了网页浏览器,可以直接预览最终生成的报告。

最后,让我们通过一个例子来感受R Markdown的实用性。

你正在观看的这套课程幻灯片,就是用R Markdown编写的。虽然这些幻灯片中没有包含R代码(因此更接近纯Markdown),但它们是利用 slidify 包构建的,该包在底层调用了 knitrmarkdown 包来将源文件转换为HTML格式的幻灯片。这展示了基于R Markdown(或纯Markdown)的格式语言具有高度的灵活性,能够被转换成多种不同的演示风格和输出格式。

本节课中我们一起学习了R Markdown的基础知识。我们了解到,R Markdown是Markdown语言与R代码的结合,它允许我们在撰写文档时直接嵌入并执行R代码,从而创建动态、可重复的数据分析报告。我们介绍了其核心概念、优势以及使用 knitrmarkdown 包进行处理的基本工作流程。掌握R Markdown是迈向高效、透明、可重复的数据科学研究的重要一步。

在本节课中,我们将学习如何创建和编辑一个 R Markdown 文档。我们将从打开 RStudio 开始,逐步创建一个包含文本、R 代码、数据分析和可视化的完整文档,并最终将其编译成格式优美的 HTML 报告。


首先,在 RStudio 中创建一个新的 R Markdown 文档。你可以通过菜单栏选择 File -> New File -> R Markdown... 来完成。

RStudio 会自动生成一个包含示例内容的文档,这有助于初学者了解 Markdown 的基本结构。

为了查看默认文档的效果,我们可以直接点击 Knit 按钮(通常显示为 Knit to HTML)来编译它。

在首次编译时,系统会提示你保存文件。将文件命名为 Markdown_demo.Rmd.Rmd 是 R Markdown 的标准文件扩展名)。编译过程会执行文档中的所有 R 代码,并将结果(包括文本、代码和输出)嵌入到一个 HTML 文件中。

编译完成后,你会在 RStudio 的内置浏览器中看到一个格式清晰的报告。它包含了标题、文本段落、置于灰色框中的 R 代码,以及代码执行后生成的输出(如文本结果和图表)。这种方式的好处是,所有内容都集成在一个文档中,无需单独生成和插入图表。

当然,默认生成的文档并非我们最终想要的。接下来,我们将清空示例内容,从头开始构建自己的报告。

首先,我们添加一个标题和介绍性文字。

我的第一个 R Markdown 文件 =========================================================== 这是我的第一个 R Markdown 文件。下面我们将加载一些数据进行分析。 

在 Markdown 中,在文本下方添加一行等号(=),可以将该文本设置为一级标题。

现在,我们添加第一个 R 代码块来加载并查看数据。R 代码块由三个反引号()包裹,并在起始反引号后的大括号内注明语言为 {r}

{r} # 加载 datasets 包中的 airquality 数据集 library(datasets) data(airquality) # 查看数据摘要 summary(airquality) 
 当你在编辑器中输入 `{r}` 后,该区域的语法高亮会发生变化,表明你正在编写 R 代码。这个代码块的作用是加载 `airquality` 数据集(一个关于臭氧等环境指标的数据框),并输出其统计摘要。 添加第二个 R 代码块与图表 在第一个代码块之后,我们可以添加一些描述性文本,然后插入第二个代码块来创建可视化图表。 以下是创建散点图矩阵的代码块: r {r} # 绘制变量间的散点图矩阵 pairs(airquality) 
 ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_6.png) 编译并查看结果 保存文件(快捷键 `Cmd+S` 或 `Ctrl+S`),然后再次点击 `Knit` 按钮进行编译。 ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_6.png) 编译后的报告将依次显示: 1. 我们添加的标题和文本。 2. 第一个代码块及其输出:即 `airquality` 数据集中各变量的摘要统计信息(如中位数、均值、缺失值数量等)。 3. 第二个代码块及其输出:一个展示数据集中所有变量两两之间关系的散点图矩阵。 添加回归分析 为了展示更完整的分析流程,我们接下来添加一个线性回归模型。 ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_8.png) 在图表之后,我们添加第三个 R 代码块来拟合一个模型,探究臭氧浓度与风速、太阳辐射和温度的关系。 r {r} # 拟合线性回归模型 library(stats) fit <- lm(Ozone ~ Wind + Solar.R + Temp, data = airquality) # 查看模型摘要 summary(fit) 
 保存并再次编译文档。 ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_10.png) 在生成的 HTML 报告中,回归模型的代码和详细结果(包括系数、标准误和 P 值等)会紧跟在散点图矩阵之后。结果显示,风速、太阳辐射和温度这三个变量都与臭氧浓度显著相关。 ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_10.png) ![](https://github.com/OpenDocCN/dsai-notes-zh/raw/master/docs/jhu-ds-5/img/87ad2faeab2bf97ed9dc81f7d13c7816_11.png) 其他格式元素 除了标题、段落和代码块,R Markdown 还支持许多其他格式。例如,你可以轻松地创建无序列表。 在文档末尾添加以下 Markdown 语法: markdown 分析要点: * 数据加载与概览 * 探索性可视化 * 统计建模 

保存并编译后,你会在报告底部看到一个带项目符号的列表。

此外,你还可以在 R Markdown 中嵌入原始 HTML、LaTeX 数学公式(通过 knitr 包支持)等高级内容,以满足更复杂的排版需求。


本节课我们一起学习了 R Markdown 的基本操作。我们掌握了:

  1. 创建文档:在 RStudio 中新建 R Markdown 文件。
  2. 基础结构:编写标题、文本段落。
  3. 嵌入代码:使用 {r} ... 语法插入并执行 R 代码块。
  4. 生成报告:通过 Knit 功能将 .Rmd 文件编译为包含所有结果(文本、代码、图表、表格)的 HTML 报告。
  5. 添加格式:使用简单的 Markdown 语法(如列表)来增强报告的可读性。

R Markdown 的核心优势在于将数据分析的代码、结果与说明文字无缝整合在一个可重复执行的文档中。你现在可以打开 RStudio,尝试创建和编辑你的第一个 R Markdown 文件了。

在本节课中,我们将学习文学化统计编程的基本概念,这是实现可重复研究的关键工具之一。我们将探讨如何将数据、代码和分析文本整合到单一文档中,以便他人能够轻松理解和复现你的分析过程。


在之前的课程中,我们讨论了可重复研究的基本理念。现在,我们将介绍一种具体工具,帮助你让他人能够复现你的分析。这种方法的核心是文学化统计编程

文学化统计编程的基本思想是,作者通常需要花费大量精力将数据和结果发布到网络上。然而,即使所有材料都已公开,数据、代码和文档往往是分离的。这可能导致混淆,例如不清楚哪段代码对应哪个数据集,或者执行代码的正确顺序是什么。

为了解决这个问题,我们可以将数据、代码和分析文本整合到同一个文档中。这样,他人可以按照正确的顺序执行代码,并在适当的时间读取数据。最终,我们得到一个集成了数据分析、代码和文字描述的单一文档,所有内容都紧密相连。

文学化编程的原始概念由斯坦福大学的计算机科学家 Don Knuth 提出。他最初设计该系统是为了在编写常规计算机程序的同时,记录代码文档。这一理念同样适用于文学化统计编程,即在同一文档中记录分析过程并包含分析代码。

文学化编程文档可以看作是由文本和代码块组成的流。其中,展示代码负责格式化表格和图形,文章文本则解释分析过程。这类文档可以通过两种方式处理:编织成人类可读的文档,或拆解成机器可读的代码文件。


文学化编程作为一个通用概念,需要一种文档语言和一种编程语言。例如,早期由 Fritz Leisch 开发的 Sweave 系统使用 LaTeX 作为文档语言,R 作为编程语言。

在本课程中,我们将重点介绍 knitr 工具,它支持多种文档和编程语言。


实现可重复研究的基本前提是决定去做。你可以在分析过程的任何阶段做出这个决定,但通常最容易在开始时进行。如果在分析结束时才决定,可能会非常困难甚至无法实现。

以下是实现可重复研究的一些关键步骤:

  • 使用版本控制系统:例如 Git 或 SVN。这有助于跟踪分析过程中的所有更改。
  • 使用可编码的统计软件:选择那些操作可以通过代码记录的软件。这通常排除了图形用户界面,除非这些界面能生成或记录操作代码。像 R 这样的系统要求显式编程,因此只要保存代码,就能完整记录对数据的所有操作。
  • 避免保存中间输出:这里的“输出”主要指临时数据转换对象。例如,如果你对原始数据进行了预处理并得到了一个干净的数据集,与其保存这个干净的数据集,不如保留原始数据以及预处理代码。这样不仅能重现最终结果,还能清晰展示从原始数据到最终数据的完整过程。
  • 避免使用专有数据格式:专有格式的数据布局不公开,可能使没有特定软件的人无法读取数据。使用非专有格式(即使是压缩的文本格式)能大大提高研究的可复现性。

文学化编程是实现可重复研究的工具之一,但它并非唯一选择。以下是它的一些优缺点。

  • 整合内容:它迫使你将分析的所有文本和代码整合到一个地方,并按逻辑顺序组织。
  • 自动更新:数据和结果会自动更新以反映外部变化。当你重新处理文档时,所有内容都会自动更新,避免了数字过时或内容不匹配的问题。
  • 回归测试:由于最终文档需要通过运行代码来生成(即编织过程),这本身就像一种回归测试。如果分析中引入了错误导致代码无法运行,你会立即发现问题。

  • 文档编辑复杂:当分析代码量很大或非常复杂时,人类可读的文本会与大量代码混合在一起,这可能使编辑文档变得困难,因为你需要在整个文档中搜索文本部分。
  • 处理速度可能较慢:如果分析非常复杂,每次想要查看文档的人类可读版本时都需要重新处理整个文档,这可能会显著减慢文档的构建过程。

本节课我们一起学习了文学化统计编程的概念及其在实现可重复研究中的重要性。我们了解到,通过将数据、代码和文本整合到单一文档中,可以极大地提高分析的可复现性和透明度。我们还探讨了实现可重复研究的一般原则,并分析了文学化编程工具(如 knitr)的优缺点。在接下来的课程中,我们将深入探讨 knitr 的具体使用方法。

在本节课中,我们将要学习一个名为 knitr 的工具,它可以帮助你创建可重复的研究文档。我们将了解 knitr 是什么、它的用途、以及如何使用它。


knitr 是一个可以帮助你制作可重复文档的工具。

具体来说,knitr 是一个由爱荷华州立大学研究生 Yihui Xie 编写的 R 语言包。它可以从 CRAN 获取。如果你使用 RStudio,knitr 已经内置其中,并与图形用户界面集成,因此无需单独安装。

在文档语言方面,knitr 支持 R MarkdownLaTeXHTML 这三种常用语言。它可以导出为 PDFHTML 格式,也可以通过 Pandoc 等外部工具导出为其他格式。正如刚才提到的,为了方便用户,它已直接集成到 RStudio 中。


要使用 knitr,你需要满足以下几个条件:

  • 一个较新版本的 R:这是运行 knitr 的基础环境。
  • 一个文本编辑器:你可以使用 RStudio 自带的编辑器,或者任何其他文本编辑器。
  • 一些支持包:这些包可以从 CRAN 获取。如果你使用 install.packages() 函数,它们会自动下载。
  • 掌握三种文档语言之一的知识:你需要了解 MarkdownLaTeXHTML 中的至少一种。本教程将重点介绍 Markdown,因为它是一种相对简单易懂的语言。


Markdown 是常见标记语言的简化版本。像 LaTeX 和 HTML 这样的标记语言,其特点是在普通文本中添加标签和注释来指示文本的格式。标记语言的一个问题是,由于存在大量标签,有时会使得原始文本难以阅读。

Markdown 的目的就是简化这一切,使其易于阅读。它只包含少量简单直观的格式化元素,你只需要将它们输入文档即可。它不需要特殊的编辑器,使用任何标准文本编辑器(如记事本)都可以。

你可以在 daringfireball.net/projects/markdown 这个网站上找到所有相关文档。


在创建可重复文档方面,我个人认为 knitr 非常适合以下场景:

  • 手册:如果你想指导他人如何使用某个软件。
  • 短篇或中篇技术文档:用于解释某些技术概念。
  • 教程:这类似于手册,但可能更深入,是关于某个主题的扩展教程。
  • 报告:报告尤其有用。例如,如果你需要每周基于某个数据库或数据集生成报告(比如在研究项目中,受试者不断加入,你需要每周生成包含研究摘要统计数据的报告),这类“动态”文档非常实用。因为你可以在生成文档时重新计算所有摘要统计数据,无需手动计算再单独插入报告。
  • 数据预处理:在预处理数据以创建干净数据集时,创建一个 knitr 类型的文档通常很有用。该文档可以记录你对数据集所做的所有操作(例如,删除异常值、填补缺失数据、转换变量等)。在这种 knitr 风格的文档中,你可以同时说明你做了什么,并在代码中实际执行这些操作。


在我看来,knitr 不太适合以下情况:

  • 非常长的研究文章:如果你在进行非常复杂、深入的分析,因为所有内容都存储在一个文档中,当代码和文本量很大时,编辑这个文档可能会有点混乱。
  • 计算非常复杂或耗时:如果你的计算非常耗时,那么 knitr 通常不是一个好选择,因为每次你想查看文档时都必须重新编译它,这会拖慢整个过程。
  • 需要非常精确的格式排版:如果你需要创建对格式有特殊要求的文档(例如,图片和文本必须放在特定位置),knitr 也不是一个非常理想的工具,因为它的格式设置往往比较随意。

本节课我们一起学习了 knitr 工具。我们了解到 knitr 是一个用于创建可重复文档的 R 包,它支持 R Markdown、LaTeX 和 HTML 等语言,并能导出为多种格式。我们探讨了使用 knitr 所需的条件,介绍了其核心支持的简化标记语言 Markdown。最后,我们分析了 knitr 适用的场景(如手册、报告、数据预处理)以及其局限性(如不适合超长文章或需要精密排版的文档)。掌握 knitr 能帮助你更高效地生成动态、可重复的分析文档。

在本节课中,我们将学习如何创建一个基础的 knitr 文档。我们将重点介绍在 RStudio 环境中创建的方法,因为这是最简单的方式。当然,这并非 RStudio 的专属功能,但我们将以此为例进行演示。

上一节我们介绍了 knitr 的基本概念,本节中我们来看看如何实际操作。

在 RStudio 中,点击左上角的“新建文档”按钮,你会看到多个选项。选择“R Markdown”选项,即可创建一个新的 R Markdown 文件。






























这个新文件将包含你的文本和代码。R Markdown 本质上是嵌入了 R 代码的 Markdown 文档。

以下是一个基础的 R Markdown 文档示例。你可以看到,一个特殊的符号表示代码块的开始。

# 这是一个代码块示例 set.seed(123) x <- rnorm(100) mean(x) 

具体来说,三个反引号 后跟花括号 {r} 表示一个 R 代码块的开始。在上面的例子中,有三行 R 代码:设置随机种子、生成一些随机正态变量、计算均值。代码块以三个反引号结束。














































在这个带阴影的代码区域上方,是文本内容。例如,标题是“我的第一个 knitr 文档”,接着是一行文本“这是一些文字”,然后是“这是一个代码块”的说明,之后才开始代码块。














在 RStudio 中,你将同时看到代码块和文本块。我们的目标是处理这个 knitr 文档,生成人类可读的输出。这意味着你需要运行 R 代码,执行这三行命令,然后将 R 代码的输出结果嵌入到你的文档中。

这段 R 代码的输出是什么?它只做了一件事:计算均值。因此,它会生成该模拟数据集的均值。














































在 RStudio 中,这非常简单。你只需点击“Knit HTML”按钮,它会自动为你运行所有内容。

如果你不使用 RStudio,也可以通过以下方式操作。

以下是具体步骤:

  1. 使用 library 函数加载 knitr 包:library(knitr)
  2. 确保你的工作目录设置为 R Markdown 文档所在的位置。
  3. R Markdown 文档通常具有 .Rmd 扩展名(大写或小写均可)。这不是必须的,但有助于识别这类文件。
  4. 如果你想创建一个网页,可以使用 knit2html 函数。






























knit2html 函数会自动处理 R Markdown 文件,运行其中的 R 代码,并将输出结果放入文件中。在 R 中,如果你想在网页浏览器中打开这个文件,可以使用 browseURL 函数。

具体来说,knit2html 函数会读取你的 R Markdown 文档,创建一个同名的 HTML 文件,然后你就可以在浏览器中打开了。






















这是你将得到的输出,即 HTML 格式的结果。你可以看到大标题、一些常规文本。代码显示在带阴影的框中,而代码的输出结果直接显示在下方。例如,均值是 0.1089,这来自 mean 函数的输出。






















那么,这里发生了什么?knitr 会获取你原始的 R Markdown 文档(如左侧所示),并将其处理成一个常规的 Markdown 文档。

你可以看到,其中一件事是它获取你的代码,并在常规 Markdown 文档中重现这些代码。但在 Markdown 文档中,它多做了一件事:将 R 代码的评估结果(显示在底部)添加到了 Markdown 文档中。这是在评估 R 代码之后完成的。






























了解基本流程后,我们需要注意一些关键点。

首先,当你在 RStudio 中创建新的 knitr 文档时,它会用一些通用的填充文本预填充该文档。你可能想做的第一件事就是删除这些文本,因为它们很可能与你想要做的内容无关。

关于代码块,它们以三个反引号和花括号 {r} 开始,并以三个反引号结束。

你所有的 R 代码都放在这些标记之间。现在,你可以有多个代码块,数量不限。你不必将所有 R 代码都放在一个代码块中。但是,任何你有的 R 代码都必须放在由三个反引号指示的代码块中。

你可以为代码块命名。在花括号内的 r 后面,你可以立即放一个名字,可以是任何你想要的,然后以花括号结束。

默认情况下,代码块中的代码会在输出文档中回显。就像在 HTML 文档中看到的那样,它回显了代码,然后给出了该代码的结果。默认情况下,所有代码块中的代码都将在文档中可见。

本节课中,我们一起学习了如何创建基础的 knitr 文档。我们从在 RStudio 中创建 R Markdown 文件开始,了解了其基本结构,即文本与嵌入的 R 代码块相结合。我们演示了如何通过点击按钮或使用 knit2html 函数来处理文档,从而生成包含代码及其运行结果的可读输出(如 HTML 网页)。我们还探讨了 knitr 的工作原理,即将 R Markdown 转换为包含代码输出的标准 Markdown,并掌握了一些实用技巧,如删除模板文本、使用多个代码块以及为代码块命名。掌握这些是进行可重复研究文档编写的重要一步。

在本节课中,我们将深入学习 knitr 包的高级功能,包括如何控制代码和结果的显示、在文本中嵌入计算结果、添加图表和表格,以及如何设置全局选项和缓存机制。这些技巧将帮助你创建更专业、更高效的可重复研究报告。


knitr 文档的处理遵循特定的流程。首先,R Markdown 文档被处理并生成一个 Markdown 文档。然后,这个 Markdown 文档被转换为 HTML 文件。最终,你查看的是这个 HTML 文件。

一般来说,你不应该编辑或修改任何中间生成的文档。这意味着不要编辑 Markdown 文档或 HTML 文档,因为它们是自动生成的。如果你编辑了这些文件,然后重新处理原始的 R Markdown 文档,你在 HTML 或 Markdown 文件中的所有更改都会被覆盖。因此,只编辑包含原始文本和原始 R 代码的 R Markdown 文件


上一节我们了解了文档的处理流程,本节中我们来看看如何控制代码块在最终报告中的显示方式。

以下是一个示例。我创建了第一个 knitr 文档,设置了作者姓名,并开始了一个名为“引言”的章节。我添加了一些文本和一个代码块,并将这个代码块命名为“simulation”。我注意到我添加了选项 echo = FALSE,这指示 knitr 不要在输出文档中显示此代码块的代码,只显示结果。

  • 一级标题 使用单个 # 表示。
  • 二级标题 使用两个 表示。
  • echo = FALSE 选项意味着不显示代码。

现在,在输出文档中,你看不到代码,只看到计算结果(例如均值)。

你同样可以选择隐藏结果。虽然在这个例子中意义不大,但你可以通过添加 results = "hide" 选项来实现。这样,在输出文档中,所有文本都在,但既没有代码,也没有结果。


knitr 文档的一个优点是,你可以在句子和文本中直接插入计算出的数字或统计量。

例如,我有一个代码块用于计算当前时间(使用 Sys.time() 函数)并生成一个随机数。我不希望人们看到这段代码,所以我设置 echo = FALSE。我希望人们看到的是紧随其后的句子:“当前时间是 [插入当前时间]”,以及“我最喜欢的随机数是 [插入随机数]”。

在输出中,你会看到类似这样的句子:“当前时间是 2013年9月4日,星期三 [具体时间]”,以及“我最喜欢的随机数是 1.1829”。这就是如何在文本行内嵌入计算变量或结果。


任何报告的一个重要部分都可能包含图表,用于可视化数据。你可以轻松地将图表添加到 knitr 文档中。

这里我模拟了一些数据。在第一个 R 代码块中,我模拟了数据。在第二个代码块中,我使用 par() 函数设置画布、边距和 las 选项,然后调用 plot() 函数生成图表。我添加了一个选项 fig.height = 4,这使得图表比通常更“扁”一些,呈现为矩形而非正方形。

knitr 生成 HTML 文件的方式很有趣。它创建了一个独立的 HTML 文件。如果你熟悉 HTML,可以看到这是一个基本的 HTML 结构。在底部,你会看到一个 标签。但它并非指向一个外部图像文件,而是将整个图像以 Base64 编码 的形式直接嵌入到 HTML 文件中。

这意味着这个 HTML 文件是独立的,不依赖于任何外部图像文件。虽然这不是最高效的格式,但它非常实用,因为你可以将这个 HTML 文件直接发给别人,他们无需担心是否拥有其他文件,因为所有内容都已嵌入。

最终结果中,我显示了 R 代码和绘图结果,你可以看到一个矩形形状的散点图。


另一个方便的功能是在 knitr 文档中制作表格。通常,你可能需要制作一个表格来总结某些计算结果,比如回归模型。

这里有一个代码块加载数据,并拟合一个线性回归模型(臭氧浓度作为风速、温度和太阳辐射的函数)。我想以一种美观的格式总结这个线性回归模型的输出,而不是标准的 R 模型输出格式。

我将使用 CRAN 上可用的 xtable 包(需要单独安装)。我使用 xtable() 函数来总结拟合结果,并将其以 HTML 格式打印出来。

在处理后的 HTML 输出中,你可以看到运行回归模型的代码被回显出来。在最底部,有一个格式化为 HTML 的回归系数、标准误、t 值和 p 值表格,这比标准的文本模式更美观。


有时,你可能希望为整个文档设置选项,这些被称为全局选项,它们将应用于每一个代码块。例如,如果你希望所有代码块都不显示代码(echo = FALSE),在每个代码块中都指定会很麻烦。这时,设置全局选项就很有用。

你可以通过在文档最开头创建一个单独的代码块(例如命名为“set-options”)来实现。有一个特殊的对象叫 opts_chunk,它内置了一个 set 函数。调用这个 set 函数,你就可以设置全局选项。

例如,我可以设置 echo = FALSEresults = "hide"。这样,默认情况下,本文档中的每个代码块都不会回显代码,并且会隐藏结果。

当然,你可以在特定的代码块中覆盖这些默认设置。例如,在第一个代码块中,我可能希望显示代码(echo = TRUE),而在第二个绘图代码块中,我可能不显示绘图代码,让默认设置生效。


以下是一些需要记住的常用选项(当然,你也可以随时查阅 knitr 网站的文档):

  • results: 可以指定为 "hide"(隐藏)或 "asis"(原样输出,不进行后处理)。
  • echo: 可以是 TRUEFALSE,控制是否显示代码。
  • 图形选项: 通常你可能需要修改图形的高度和宽度,例如 fig.widthfig.height

一个特殊情况是,当某个代码块的计算需要很长时间才能运行时,每次处理 knitr 文档以查看 HTML 输出时,你都必须重新运行这个计算。

为了避免长时间等待,一个策略是缓存计算结果。这对于复杂的代码块非常有用。其思想是,对于每个代码块,你可以设置一个特殊选项 cache = TRUE

第一次处理文档时,它必须运行代码以确定输出是什么。然后,它会将该输出存储在磁盘上。下次处理文档时,只要没有任何更改,它就会从磁盘加载结果,这通常比重做所有计算要快得多。如果你需要反复处理文档,这将节省大量时间。

如果数据或代码发生了变化,那么你将不得不重新运行代码,这是无法避免的,缓存也会相应更新以反映新结果。

默认情况下,knitr 不会显式跟踪代码块之间的依赖关系。因此,如果前面的代码块发生了重大变化,而下游的代码块依赖于它,你需要确保重新运行所有相关部分,以免缓存数据混淆。

此外,具有显著副作用的代码块(例如,修改外部文件或环境)可能无法被正确缓存。


本节课我们一起学习了 knitr 的高级功能。knitr 是一个用于实现文学化统计编程的强大工具,它允许你将文本、代码、数据和输出全部整合到一个文档中。它使用简单易学的 Markdown 格式化语言,并生成可以在任何网络浏览器中查看的 HTML 文档。

尽管它并非完美无缺的工具,但对于整合文本和代码、生成可重复的研究报告来说,学习和掌握 knitr 是非常有用的。

在本节课中,我们将学习如何完成并提交课程的第一个项目。项目要求你完成一项数据分析,并使用R Markdown和knitr撰写报告。提交过程涉及将你的工作上传至GitHub,并提交特定的提交哈希值以供评估。


要成功提交本次作业,你需要完成两件事。首先,你需要进行一项相对简单的数据分析。其次,你需要使用R Markdown和knitr撰写一份报告。

为了提交作业,你需要:

  1. 将你的项目文件检入一个GitHub仓库。
  2. 将该仓库推送到GitHub。
  3. 提交你的GitHub仓库链接。
  4. 提交一个特定的Sha1哈希值,该值标识了你用于提交的仓库状态。

这样,评估者就能知道你仓库中哪个版本的文件是用于本次作业的正式提交。在Git仓库中,文件会不断变化,通过不同的提交记录变更。因此,需要明确哪个提交对应你的正式作业。


上一节我们介绍了项目的基本要求,本节中我们来看看如何具体操作,获取并提交所需的GitHub仓库链接和哈希值。

其次,你需要找到代表你提交状态的特定提交的Sha1哈希值。

以下是获取该哈希值的步骤:

  1. 在你的GitHub仓库页面,找到“commits”(提交)链接或数量统计。
  2. 点击进入提交历史列表。最新的提交会显示在最顶部。
  3. 在每条提交记录的右侧,你会看到一个缩写版的Sha1哈希值。
  4. 将鼠标悬停在该哈希值上,会出现一个复制到剪贴板的图标。点击它即可复制完整的哈希值。

如果你想提交的不是最新版本,而是更早的某个提交,只需在提交历史列表中向下滚动,找到对应的提交记录,然后复制其哈希值即可。


在同伴互评环节,你需要评估他人提交的作业。为此,你需要访问他们提供的GitHub仓库URL,并定位到他们指定的提交快照。

以下是查看他人特定提交的步骤:

  1. 访问对方提供的GitHub仓库URL。这会显示仓库的最新状态。
  2. 点击“commits”进入提交历史列表。
  3. 在列表中,找到与对方提供的Sha1哈希值相匹配的提交记录。
  4. 点击该提交记录旁边的“browse code”(浏览代码)按钮。

点击“browse code”后,你将看到该仓库在那个特定提交时刻的完整快照。这就像回到了项目在那一刻的状态。你可以查看当时所有文件的内容。

例如,如果你想查看2012年3月12日的仓库状态,只需找到该日期的提交,然后点击“browse code”即可。


本节课中我们一起学习了课程项目1的提交流程。你需要完成数据分析并撰写报告,然后将工作推送到GitHub仓库。提交时,需提供仓库的URL和标识特定提交状态的Sha1哈希值。在评估他人作业时,你也需要利用这些信息在GitHub上定位到对应的项目快照。这个过程确保了评估基于明确、可复现的代码版本。

在本节课中,我们将要学习如何有效地传达数据分析的结果。虽然这并非严格意义上的“可重复研究”本身,但它关乎如何以一种他人能够理解、并在必要时能够验证的方式呈现你的发现。特别是当你进行大型或复杂的项目,并以可重复的方式工作时,你会生成大量内容、文件、输出和数据。这些内容无法一次性全部呈现。因此,当你向他人展示成果时,需要遵循一个从最不具体到最具体的信息层级结构。

上一节我们介绍了可重复研究的基本概念,本节中我们来看看如何组织并呈现你的研究成果。核心思想是,如今的管理者和组织领导者通常非常繁忙,他们需要你以分层的方式呈现内容,以便快速抓住重点。

很多时候,数据分析结果会以口头形式(如演示或会议)呈现,但早期或中期结果通常通过电子邮件等媒介传达。将分析结果分解为不同特异性或粒度的层级非常有用。

以下是一些关于如何从繁忙人士那里获得电子邮件回复的通用建议链接。基本理念是,不要一次性向某人发送大量信息,因为这会让人不知所措,降低他们阅读你内容的意愿。

如果你思考一篇典型的研究论文,会发现其中内置了信息层级结构。

通常,第一层级是标题。标题描述了论文的主题,希望它有趣并能让你大致了解内容,但标题本身没有细节,仅涵盖主题。

下一层级是摘要。摘要通常有几百字,说明论文内容、问题动机、解决方法以及最重要的结果。

当然,接下来是论文正文。正文会展示更多细节,包括方法、更详细的结果、敏感性分析等内容,以及对结果含义的更深入讨论。

然而,即使是如今的书面论文,对于复杂的数据分析,也无法详细说明重现发现所需的所有细节。

因此,通常会有一些补充材料,其中包含更多关于所做工作的细节。

如果你真的想精确地复现所做的工作,可能需要获取代码、数据以及所有繁琐的细节。

这就是你可能呈现的信息范围,从最不具体到最具体。

并非每个人都会撰写研究论文,但大多数数据分析的呈现方式都有类似之处。

上一节我们以研究论文为例了解了信息层级,现在将其应用于更常见的电子邮件沟通场景。

如果你要通过电子邮件向同事或经理发送结果,那么第一层信息就是电子邮件的主题

电子邮件的主题类似于标题,你需要让它简洁、具有描述性。至少应该有一个主题,不要发送没有主题的邮件。如果你能用一句话总结你所做的工作,将其放在主题中可能很有用。

这样,阅读主题的人就能大致了解情况,甚至可能仅凭此做出决定。

下一层信息当然是电子邮件正文。尽管电子邮件正文的大小没有技术限制,但也不要过于冗长。你需要提供问题的简要描述。

如果收件人同时处理许多不同事务,可能不记得你正在处理的具体问题,因此需要提供一些背景和描述。可以回顾之前的会议,讨论提议的内容以及你实际所做的工作。总结你的发现和结果。整个电子邮件正文总共一到两段即可。

如果你需要信息接收者根据此演示结果采取某种行动,那么你应该尝试提出一些选项,并尽可能使其具体化。如果有需要解决的问题,你希望他们回复答案,通常最好尝试让问题尽可能简单,例如是/否问题。

在电子邮件正文之后,你当然可以附加更长的内容,例如PDF文件或其他类型的文档。

这可以是一份包含更详细分析、图表、表格等的报告。这份报告可以源自R Markdown文件,你可以使用knitr创建它。但即使在这样的报告中,你可能有几页的篇幅来呈现内容,你仍然需要保持简洁,不要输出大量代码、表格和结果。

我们知道你的代码是可用的,因为如果你使用像knitr这样的工具,显然需要将代码与结果放在一起。但你不必在报告中全部呈现。

当然,如果有人真的想精确查看你所做的工作,你可以给他们一个链接,指向像GitHub或项目网站这样的代码仓库,那里包含你所有代码文件、数据集、所有繁琐细节以及软件环境等所有详细信息。

本节课中我们一起学习了如何分层级地传达数据分析结果。

这就是你可能想向某人呈现的不同详细程度。那些对你所做的一切真正感兴趣或确实想知道细节的人,可能会访问你的GitHub仓库,开始拉取你的代码并查看详细结果。而那些只需要高层总结的人,会阅读邮件主题、简要描述,并可能翻阅报告。

关键在于,不同的人对你所做工作的不同细节层次感兴趣。因此,你需要向人们呈现这些不同的层级,以便他们能够选择自己最感兴趣的层次。这只是一个关于如何呈现你分析过的数据或项目的通用模板。并非每次演示都需要所有这些不同的层级,但我认为这是一个有用的分类,涵盖了你可以进行的各种演示类型。

在本节课中,我们将学习如何使用RStudio提供的RPubs服务,将R Markdown文档发布为公开的网页,以便与他人分享你的数据分析成果。


RPubs是RStudio提供的一项免费服务,允许用户将R Markdown文档编译后的HTML结果发布到公共网站。这为分享统计分析、报告和可视化结果提供了便捷的途径。

上一节我们介绍了如何使用R Markdown和knitr生成动态报告。本节中,我们来看看如何将这些报告发布到网上,实现真正的可重复与可分享研究。


使用RPubs的第一步是注册一个账户。

以下是注册步骤:

  1. 访问 rpubs.com。
  2. 点击注册,填写姓名、邮箱、用户名和密码。
  3. 完成注册后,即可登录并开始发布内容。

在发布之前,需要确保你的R Markdown文档能正确编译为HTML。

以下是操作流程:

  1. 在RStudio中打开或创建一个R Markdown(.Rmd)文件。
  2. 点击 Knit 按钮,在预览窗口中查看生成的HTML输出。
  3. 确认报告内容正确无误,例如包含数据加载、分析和可视化代码及其结果。

例如,一个简单的分析可能包含以下代码块:

# 加载空气质量数据集 data(airquality) # 绘制变量关系图 pairs(airquality) # 拟合线性模型 model <- lm(Ozone ~ Wind + Solar.R + Temp, data = airquality) summary(model) 

当文档准备就绪后,即可将其发布到RPubs。

以下是发布步骤:

  1. 在RStudio的HTML预览窗口顶部,找到并点击 Publish 按钮。
  2. 系统会弹出RPubs发布提示框,点击 Publish
  3. 如果你的浏览器已登录RPubs账户,会直接跳转到发布页面;如果未登录,系统会引导你登录。
  4. 在发布页面,为你的报告设置一个标题和描述。
  5. 你可以自定义URL标识符,或使用系统自动生成的ID(例如 11879)。
  6. 点击 Continue 完成发布。

发布完成后,你会获得一个永久的公开URL(如 https://rpubs.com/你的用户名/11879),任何人都可以通过此链接访问你的报告。


报告发布后,你可以方便地与他人分享或进行管理。

以下是可用的功能:

  • 分享:使用页面上的分享按钮,可以将报告链接发送到社交媒体或通过邮件分享。
  • 评论:访客可以在报告页面下方发表评论,便于交流。
  • 删除:如果你误发布了内容或想撤销分享,可以随时在页面底部找到删除选项将其移除。

重要提示:所有发布到RPubs的内容都会立即公开,不存在私密期。因此,请务必在发布前仔细检查,确保没有包含任何敏感或不想公开的信息。


本节课中,我们一起学习了如何使用RPubs服务。我们了解了从注册账户、准备R Markdown文档,到最终发布和分享分析报告的完整流程。RPubs是一个强大且免费的工具,它能将你用R Markdown和knitr创建的可重复分析快速转化为可公开访问的网页,极大地促进了研究结果的传播与协作。

记住,虽然分享很方便,但始终要注意数据的公开性与隐私安全。现在,你可以尝试发布自己的第一个分析报告了。

在本节课中,我们将学习一份简短的核对表,用于指导任何涉及大量数据处理与分析的项目。这份清单基于经验总结,旨在帮助你建立可重复研究的基础实践。


上一节我们介绍了课程目标,本节中我们来看看核对表的第一项:确保你研究的是一个好的科学问题。这是可重复研究的基石。

好的科学意味着你研究的问题本身对你和他人都有意义。如果起点不佳,最终结果很可能也不理想,这正如“垃圾进,垃圾出”的道理。因此,你需要一个相对聚焦和连贯的研究目标或问题。一个更明确的问题能简化你的工作,因为它排除了许多不必要的可能性。反之,一个宽泛模糊的问题会增加问题的复杂性。

此外,与优秀的协作者共事至关重要。良好的合作关系能促进良好实践,而糟糕的关系可能导致不良习惯。最后,确保课题是你感兴趣的,因为兴趣是维持良好研究习惯的重要动力。

核心要点:始终从一个好的、有趣的科学问题开始。


如果要将可重复性浓缩为一条核心规则,那就是:不要手动处理事务。手动操作是导致研究不可重复的最常见原因。

以下是几个常见的手动操作示例及其风险:

  • 编辑电子表格:在Excel等软件中直接清理异常值或修正数据非常方便,但除非你精确记录每一步操作和判断标准(例如,定义异常值的公式),否则这个过程完全不可重复。
  • 修改图表与表格:例如,手动调整表格中的舍入规则,可能导致他人无法复现相同结果。
  • 从网站下载数据:手动点击链接下载数据看似简单,但需要向他人提供冗长的网站、链接点击顺序等说明,过程难以精确复现。
  • 移动或拆分文件:在电脑中手动移动文件或拆分大文件,不会留下任何操作记录,他人无从重复。

在分析初期,人们常认为“这个操作只做一次,不需要自动化或详细记录”。但你必须确保,即使只做一次,其文档也需详细到让一个不了解背景的陌生人能够重复你的操作。

根本原因:任何手动操作都必须被精确记录,而这项任务远比听起来困难。许多你认为不重要的细节,对缺乏相同背景的他人而言可能至关重要。


下一项规则与第一条相关:尽量避免使用点击式的图形用户界面软件。

图形界面通常直观易用,但问题在于,你通过点击菜单和选项执行的操作,很难被他人精确复现。除非你详细记录“点击了A菜单下的B选项”,否则他人无法知晓你的具体操作步骤。

一些带有图形界面的软件会生成记录等效命令的日志文件或脚本。这些文件可以保存供未来查验。因此,对于高度交互式的数据分析或处理软件需要格外小心。交互的便利性可能以牺牲可重复性为代价。

当然,并非所有带图形界面的软件都需避免。例如,用于编写代码或报告的文本编辑器通常没有问题,因为你的分析通常不严格依赖于使用哪个编辑器。但在极少数情况下,如果分析确实依赖于此,则仍需谨慎记录。

核心建议:警惕那些不记录操作历史的高度交互式软件。


本节课我们一起学习了可重复研究核对表的前两部分核心内容:

  1. 始于好的科学:选择一个你感兴趣、目标聚焦且能与优秀协作者共同推进的问题。
  2. 自动化优于手动:避免手动编辑数据、下载文件等操作,坚持使用可记录的脚本和程序。
  3. 记录优于点击:谨慎使用不记录操作历史的图形界面软件,优先选择能生成日志或脚本的工具。

遵循这些原则,能为你的数据分析项目奠定坚实的可重复性基础。

在本节课中,我们将继续学习可重复研究核对表,重点探讨如何通过自动化、版本控制和记录软件环境来确保数据分析的可重复性。


上一节我们介绍了可重复研究的基本概念,本节中我们来看看如何通过自动化来避免手动操作带来的问题。

手动操作的“解药”是,你应该尝试教会计算机去执行你即将要做的任何事情。核心思想是,你应该尽可能自动化分析过程中的所有操作。特别是处理数据的部分,你应该始终尝试教会计算机来完成。

这样做有两个主要原因:

  1. 如果你能教会计算机执行任务,你就拥有了明确、具体的操作指令,数据分析中就没有模糊不清的空间。因为计算机通常不接受模糊的指令,它需要精确的编程指令。
  2. 当你向计算机发出指令时,本质上是在精确地写下你的意图和执行方法,而这正是可重复性的定义。

因此,如果你能教会计算机,这几乎在很大程度上保证了你的操作是可重复的。即使某个操作你只打算做一次,尝试教会计算机去做也是有益的。这可能涉及使用不同的编程语言,例如R或其他语言。虽然编程可能需要更长时间,但从长远来看,它会通过确保你所做的一切都是可重复的来回报你。

以下是一个简单的自动化示例,它演示了如何用代码替代手动操作:

# 使用R的download.file函数自动下载数据 download.file(url = "http://archive.ics.uci.edu/ml/machine-learning-databases/00275/Bike-Sharing-Dataset.zip", destfile = "./project_data/bike_sharing_data.zip") 

这个例子有几个优点:

  • 明确的URL:数据的确切来源被指定,没有歧义。
  • 明确的文件名:保存到本地的文件名也被明确指定,便于追踪。
  • 明确的保存路径:数据被保存到名为project_data的目录中。

只要使用R且网络地址未变,任何人都可以执行这段完全相同的代码来下载相同的数据。当然,你无法控制网站本身的变化,但在你能力范围内,尽可能多地使用此类代码(如download.file函数)将大大提高可重复性。


另一个通用建议是使用某种版本控制软件。在本系列课程中,我们主要关注Git,它是一个非常优秀的版本控制软件,通常与GitHub或Bitbucket等网站结合使用,用于发布代码和项目。

在数据分析项目中使用版本控制系统时,需要记住其主要特点是:它有助于让你“慢下来”。这听起来可能像件坏事,但“慢下来”通常是好的。因为当你对一个项目充满热情并急于开始分析时,你可能会直接动手处理数据,而没有记录下发生了什么。版本控制软件会促使你停下来,思考已经完成的工作和所做的更改,然后将更改提交到代码仓库,从而留下记录。

这对于数据分析非常有用,因为你拥有了工作日志,记录了你的探索路径和发现。如果你想回溯,可以轻松返回,并查看你当时发现了什么。例如,在探索性分析过程中,如果你发现了有趣的东西,你会有一个历史记录来展示你是如何到达那里的。

当然,像Git这样的软件可以用来跟踪和标记项目的快照,可以回滚到旧版本等。这些功能在版本控制系统中都是标准的。因此,建议你在推进项目时,以小块的形式添加更改,而不是一次性提交大量文件。将分析分解为逻辑片段并逐一提交,这将有助于你阅读历史记录并理解过去所做的工作。


跟踪你的软件环境对于可重复性至关重要,因为许多复杂项目会涉及串联多个工具来处理不同数据集,而某些工具和数据可能只在特定环境中有效。因此,软件和计算环境对于重现分析可能至关重要。

你的软件环境中可能需要跟踪许多方面,并非所有方面对每个项目都关键,但有一些常见事项需要留意:

以下是需要记录的关键环境信息:

  1. 计算机架构:通常不太重要,但了解你使用的CPU类型(如Intel、AMD、ARM)以及是32位还是64位系统、是否使用GPU等,在需要告知他人时是有用的。
  2. 操作系统:非常重要。你使用的是Windows、macOS、Linux还是其他版本?因为有些软件只适用于特定系统。
  3. 软件工具链:你使用的各种软件,如编译器、解释器、Shell(如Bash)、编程语言(C++、Python、R)、数据库后端、数据分析软件等。所有这些都应被记录,因为他人要重现你的工作,就需要重现整个环境。
  4. 支持软件/库:特别是软件库或R包等依赖项,需要被跟踪。
  5. 外部依赖:来自你计算机外部的依赖,例如你从中下载数据的中央存储库、查询的远程数据库或获取软件的其他软件仓库。
  6. 版本号:对于上述所有内容,记录版本号通常很重要。因为软件会更新,新版本可能会破坏依赖关系。你的项目可能只在特定版本下可重现。

一个小例子是在R中使用sessionInfo()函数。这个函数会尽可能详细地报告你的环境信息。

# 在R中运行以获取当前会话信息 sessionInfo() 

该函数的输出会显示R版本、操作系统、区域设置、已加载的基础包和附加包等信息。虽然这只是整个软件环境的一小部分,但拥有这种详细信息通常非常有用。


本节课中我们一起学习了确保可重复研究的三个关键实践:自动化数据处理步骤使用版本控制系统(如Git)管理项目变更,以及详细记录软件环境与依赖。通过实施这些策略,你可以极大地提高数据分析项目的透明度、可追溯性和最终的可重复性。

在本节课中,我们将学习关于确保数据分析可重复性的几个核心实践原则。我们将重点讨论如何管理分析输出、处理随机数,以及如何审视整个数据分析流程,以确保每一步都是可追踪和可复现的。

上一节我们讨论了文档的重要性,本节中我们来看看如何管理分析过程中产生的文件。进行数据分析时,我牢记的一条快速准则是:不要保存任何输出。这听起来可能有些奇怪,因为你最终确实需要一些输出结果。

确实如此,如果你要撰写报告或论文,你将需要表格、图形和摘要等内容。但在你真正进行最终阶段的活动之前,最好不要保存这些输出。因为一个孤立的输出文件,如果不知道它从何而来或如何产生,它就是不可重复的。

如果不可重复,那么保存它几乎毫无价值,因为你将始终困惑于那些数字是如何得到的,那个图形是如何制作的。因此,与其保存一个表格或图形这样的输出,不如保存生成该表格或图形的数据和代码。这样,你总能重新生成你需要的任何类型的输出。

当然,在一个大型项目中,分析流程会很长。

在大型项目中,分析流程可能很长,也许从原始数据开始,然后到处理后的数据,可能进一步处理数据,再进行一些分析。在这个过程中可能会生成许多中间文件,这通常是可以接受的。

保留这些文件通常没问题,因为这比每次都必须重新生成所有内容要高效得多。但是,如果你保留中间文件,关键在于你必须确保每个中间文件都有文档记录,你有生成该中间文件的代码,并且输入其中的数据集有清晰的文档记录。

因此,通常最好不保存任何输出,因为你可以转而保存代码和数据。但如果你需要保存像中间文件这样的东西,那么请确保你拥有与之配套的代码和数据。

这是一个非常具体但至关重要的问题,因为它可能导致非常不可重复的结果。如果你生成随机数,几乎所有随机数生成器都会基于一个种子生成伪随机数。

种子通常是一个数字或一组数字,用于初始化随机数生成器,然后随机数生成器按序列生成基于该种子的随机数。例如,在R语言中,你可以使用 set.seed() 函数,只需给它一个整数,它就会初始化随机数生成器。

# 示例:在R中设置随机数种子 set.seed(123) random_numbers <- rnorm(10) # 生成10个随机数 

如果你调用 set.seed() 然后生成随机数,只要你稍后再次设置相同的种子,这个随机数序列将总是可以精确复现的。

这对于模拟、马尔可夫链蒙特卡洛分析等涉及生成随机数的任何事情都很重要。你应该始终记住这样做,否则你的数字将无法复现。如果你进行了一项使用随机数但未设置种子的分析并发表了它,基本上不可能回过头去弄清楚当时的情况。因此,任何时候使用随机数都要考虑这一点

最后,我想提一下,整个数据分析和处理数据的过程通常是一个很长的流程。从获取原始数据(可能来自网络或某项调查实验),到清理、处理、分析,再到制作摘要和图形,最后生成结果,这是一个漫长的过程。

你应该在工作的同时思考整个流程,并思考每个环节是否可重复。当你沿着这个流程进行时,思考如何到达终点与你最终产出的产品(如分析报告)同样重要。最终产出的分析或报告只是你为达到目的所做全部工作的一个小子集。

事实是,你为达到目的所做的所有工作,其跟踪记录同样重要。作为一般规则,你能使数据分析流程中越多的环节可重复,对你、对他人就越好,你的结果也越可信。所以,要思考整个流程,所有环节都重要,不仅仅是最终产品重要

综合所有这些原则,我整理了一个简单的问题清单,供你在进行任何数据分析时自问。

以下是你在进行数据分析时应问自己的关键问题:

  1. 我们是在做有价值的科学吗? 这有趣吗?值得做吗?
  2. 分析的任何部分是否手工完成? 这可能无法避免,你可能必须手工做一些事情。这里唯一真正的问题是,如果你手工做了某事,它是否被精确地记录了?特别是你需要确保,如果记录了,文档是否与实际操作相符?因为很多时候,你写下文档,但后来实际上改变了你的操作(因为需要更新或发现错误)。如果你更新或改变了什么,你必须相应更新配套的文档。文档是否与你实际所做相符?
  3. 你是否尽可能多地编写了代码? 当然,你希望尽可能让计算机来完成工作。你是否尽可能多地编码,并以精确的方式写下了你所做的事情?任何时候你教计算机做某事,这都是一个好主意。
  4. 我们是否使用了版本控制系统? 你是否在使用 Git 或 SVN 之类的工具?
  5. 你是否记录了软件环境? 每个工具、每个库、你的操作系统、你的架构,这些都需要注明。
  6. 你是否保存了任何无法从原始数据和代码重建的输出? 通常,你应避免保存任何无法从某些数据和代码推导出的输出。因此,保存数据和代码比保存输出更好
  7. 在分析流程中,我们可以回溯多远,结果才不再可重复? 如果你正在处理流程中的某一部分,可能无法一直回溯到原始数据,也许只能回溯到该数据的某个处理版本,这没关系。但要思考整个流程,并尝试使其尽可能可重复。

这些是我对于通用类型数据分析项目中可重复性思考的一般性建议。我认为其中很多将帮助你组织项目,并确保你的思路正确。关键点在于:手工操作时要小心,尽可能多地编码,并尽可能精确地记录一切。

本节课中我们一起学习了确保数据分析可重复性的几个关键实践。我们强调了应优先保存生成输出的数据和代码,而非输出本身;在必须保留中间文件时,需确保其有完整的文档和生成代码。我们深入探讨了设置随机数种子对于复现涉及随机过程的分析至关重要。最后,我们通过一个核对表问题清单,引导大家从项目价值、手工操作、代码化、版本控制、环境记录、输出管理以及流程回溯等多个维度,系统审视和提升整个数据分析流程的可重复性。记住,可重复性关乎整个分析链条,而不仅仅是最终的报告。

在本节课中,我们将探讨科学研究中的两个核心概念:可重复性可复制性。我们将明确区分这两个术语,并理解它们各自在验证科学发现中的作用。课程将重点讨论为何在当前数据密集型的研究环境中,可重复性变得尤为重要。


上一节我们介绍了本课程的主题。本节中,我们来看看“可复制性”与“可重复性”这两个常被混用的概念有何本质区别。

我认为在很多情况下,人们倾向于互换使用这些词语。但为了本次讨论的目的,并且考虑到接下来基思的演讲,我们需要对它们进行区分。

当我思考“可复制性”时,我想到的是科学中通常发生的情况。在我看来,可复制性的目的是解决科学主张的有效性问题。例如,如果你声称X与Y相关,第一个问题就是:这为什么可能是真的?因此,你必须在另一项研究或一系列其他研究中,由新的研究者、收集新的数据、使用不同的分析方法、实验室、仪器等进行复制。如果经过多次复制,没有人能发现相同的结果,那么你会认为这个主张可能不成立。但如果所有独立研究都发现了大致相同的结果,那么你会认为这可能是一个合理的主张。因此,可复制性是我们一直以来做事的方式,并且我认为它仍然是加强科学证据的终极标准。

而“可重复性”,如果你还没听过这个术语,我指的是它侧重于数据分析的有效性。这里的情况是:数据已被收集并由某人分析,他们声称X与Y相关。此处的理念是,可以由新的研究者,但查看相同的数据并使用相同的方法,来验证他们所声称的结果是否确实能从数据和分析中得出。所以,我认为这里真正的问题不是“主张是否真实”,而是“我们能否信任这项分析”。这就是可重复性试图解决的关键问题:我们能否采用他们的方法,应用于他们的数据,并得到与他们相同的结果?

我认为这一点至关重要,特别是在我的工作领域,可重复性尤为重要,因为在这些领域,可复制性往往不可能实现。这就是我讨论的起点。


理解了核心概念的区别后,我们来看看当前的研究背景,这有助于理解为何可重复性问题日益凸显。

我认为一些背景情况是大家所熟悉的。近年来,关于可重复性的讨论很多。一些趋势表明,许多研究根本无法被复制,或者复制的代价极高。特别是在流行病学中,那些长达25年的队列研究,在合理的时间内根本无法复制。同时,技术极大地影响了数据收集的速度,数据的复杂性也非常高。

人们正疯狂地将各种数据库拼凑在一起——我就是其中之一。我注意到很多数据被“超范围使用”。例如,行政数据集被用于健康研究等。这非常普遍。此外,由于计算能力现在非常强大且复杂,我们可以在小型数据集上进行极其复杂的分析。现在,对于每一个领域X,都有一个“计算X”领域。

现在,即使是基本的分析结果,有时也很难在期刊的标准方法部分进行充分描述。通常,研究者被要求进行非常复杂的计算工作,但接受的培训却很少。结合我来自的背景稍作说明:你可以想象计算能力从低到高的范围。这个房间里的大多数人可能处于高端,而杰夫可能处于更高端。

但在这个光谱的低端,有大量的人无论喜欢与否,都不得不进行计算工作,因为他们手头有海量数据。这可能导致问题,错误可能被引入漫长的分析流程中。如果你无法在合理的篇幅内告诉别人你做了什么,那就会阻碍知识的传递。在许多情况下,人们有一种感觉:复杂的分析不可信


本节课中,我们一起学习了科学研究中“可复制性”与“可重复性”的关键区别。可复制性关注于使用新数据、新方法验证科学主张的真实性,是科学的黄金标准。而可重复性则关注于使用相同数据和相同方法,验证数据分析过程本身的可靠性与透明度,其核心问题是:“我们能否信任这项分析?”

我们了解到,在当前数据量激增、分析高度复杂、且某些研究(如长期队列研究)难以复制的背景下,确保研究的可重复性变得至关重要。它有助于发现分析流程中的错误,促进知识传播,并建立对复杂分析结果的信任。下一节,我们将继续深入探讨如何在实际研究中实现可重复性。

在本节课中,我们将探讨可重复研究的基本框架,分析其解决的问题与存在的局限性,并理解其在科学传播中的定位。

上一节我们讨论了可重复研究的重要性,本节中我们来看看一个典型的研究过程是如何被呈现和接收的。

通常,读者在期刊上看到的是一篇已发表的文章。这是读者能获得的全部信息。读者可以了解到研究者提出的科学问题,以及他们最终得出的结论。然而,这个过程是单向且不透明的:作者从原始问题出发,经过一系列步骤得出了文章中的结论;而读者只能从文章这个终点开始,尝试反向理解作者的路径。

在绝大多数情况下,读者除了阅读文章并表示赞叹,或者亲自去重复整个研究之外,没有其他办法能深入了解研究过程。

那么,可重复研究试图解决什么问题呢?它的基本理念是“在中间地带相遇”。

实际上,在一篇发表的文章背后,存在大量未被公开的中间过程。这包括:

  • 原始数据与测量数据
  • 对数据进行的具体分析
  • 执行分析所用的全部代码
  • 分析产生的结果、图表和表格

可重复研究倡导将这些中间材料公开。例如,公开分析所用的数据集、相关的处理代码以及重要的预处理步骤。这是一种折衷方案,它虽不能替代完整的重复研究,但极大地增强了研究的透明度。

接下来,我们具体分析可重复性带来的益处及其固有的局限。

可重复研究主要带来以下好处:

  1. 透明度:我们能更清楚地知道研究者实际做了什么。
  2. 数据可用性:分析所使用的数据变得可获取。
  3. 方法传播:如果涉及新方法,这些方法得以传播。
  4. 知识转移:我们确切知道了他们“实际做了什么”,而不仅仅是他们“意图做什么”。

然而,可重复性并不解决一个根本性问题:我们能否信任这个分析? 因为一个分析可以是完全可重复的,但同时也是错误的。例如,研究者可能使用了错误的方法或不当处理了数据。文献中存在许多这样的例子。

因此,可重复性虽然至关重要,但它并不能为分析的正确性提供保证。

最后,让我们思考一下可重复研究范式所依赖的一些前提假设。

可重复研究的前提是,当所有数据和代码都免费公开后,同行可以互相检查,验证彼此的分析,从长远看,整个科学体系能够实现自我纠正。

但这个范式存在一些问题:

  • “长远”可能太久:对于许多亟待解决的问题,自我纠正的周期可能过长。
  • 侧重于下游环节:可重复性主要解决的是科学传播中发表后的环节。
  • 理想化的假设:它假设所有人都遵守相同的规则,并追求相同的科学目标。这显然与事实不符。

本节课总结

本节课我们一起学习了可重复研究的核心框架。我们了解到,传统研究发表模式存在不透明的问题,而可重复研究通过公开数据、代码等中间材料,在透明性、数据可用性和知识传播方面做出了重要改进。同时,我们也认识到可重复性并不能保证分析的正确性,并且其有效性依赖于一些在现实中可能难以完全满足的理想化前提。理解这些优点与局限,对于在实践中推行和评估可重复研究至关重要。

在本节课中,我们将探讨如何将“可重复性”的理念从研究过程的末端,提前到更上游的环节。我们将通过一个类比来理解其重要性,并介绍一种在学术出版中实施可重复性检查的实践模型。

上一节我们讨论了研究传播中的潜在问题,本节中我们来看看如何通过流程设计,在早期介入以确保分析的可重复性。


我有时会用哮喘的病理机制来类比。在哮喘的过敏致敏和发病过程中,过敏原暴露会引发一系列反应:特异性免疫球蛋白E附着于肥大细胞,致敏后产生炎症介质,这些介质进而导致支气管收缩等典型症状。

传统的干预方式主要是药物治疗,例如吸入性皮质类固醇、白三烯调节剂或抗免疫球蛋白E药物。这些方法作用于疾病过程的中下游,效果各异。

然而,还有一部分干预作用于最上游。我对许多环境干预研究感到兴奋的原因在于,它们能影响疾病过程的最开端。这不仅作用点更早,而且相对于所有药物治疗,它通常成本更低、效率更高且潜力巨大。


如果将这个类比迁移到研究传播过程:

  1. 研究人员在此进行研究。
  2. 研究本身可能在分析上存在问题或错误。
  3. 他们将论文提交给期刊,经过流程后发表。
  4. 论文发表后,你才能获得数据和代码,并查看他们的具体操作。

传统的保障措施包括:期刊编辑初审(可能拒稿)、送交同行评审(理论上进行核查),通过后得以发表。目前,可重复研究通常在这个过程的最下游环节才介入

现在有很多关于推进此事的讨论。其核心思想是:为何要等到论文发表后才提供数据和代码?为何不将其作为出版过程的一部分?

我认为这是一个崇高的目标,但可能不完全现实。因为期望审稿人重现所有分析是不切实际的。根据我的经验,非统计学领域的研究者可能不习惯通常需要等待6到12个月的评审周期。如果在此基础上,再加上重现整个分析的要求,评审可能会被推迟到40年后。这并不合理,我稍后会举例说明。

因此,关键问题是:我们能否在这个过程的最上游部分做一些事情? 这就是我今天想讨论的内容。


以下是将可重复性部分向同行评审环节(或更上游一点)移动的一个例子。这并非完全在评审时进行,但位置更靠前。

我们在《生物统计学杂志》(这无疑是世界上最好的统计学期刊)有一项政策。我担任“可重复性副编辑”,我们有一项非常宽松且完全自愿的政策。

以下是该政策的操作流程:

  • 作者可以将数据和代码提交给可重复性副编辑(也就是我)。
  • 我将尝试重现分析。
  • 这项政策并非100%万无一失,但至今为止,我还没有遇到无法重现的情况。
  • 如果分析可重现,你的论文上会盖上一个漂亮的 R 印章。

此外还有两个其他选项:

  • C:如果你提交了代码,会获得一个 C 标记(我不检查,默认没问题)。
  • D:如果你提交了数据,会获得一个 D 标记。
  • 如果你既提交数据又提交代码,你会获得 DC。如果我成功重现,你会获得 R

例如,杰夫对此工作的唯一贡献就是获得了一个 R。我花了一周时间重现,但过程顺利。

总之,这是一种模型。它并非强制性的威慑手段,因为完全是自愿的,且发生在论文通过同行评审并被接受之后。但这仍然是一种可能的实践模型。


本节课中,我们一起学习了通过“上游干预”来提升研究可重复性的理念。我们通过哮喘治疗的类比,说明了在流程早期介入的优势,并介绍了一种在学术期刊中实施的自愿性可重复性检查模型。将可重复性检查整合到出版流程中,是迈向更可靠、更透明科学研究的重要一步。

在本节课中,我们将探讨一个可重复研究中的核心问题:谁来进行研究复现?我们将分析不同群体的动机,并讨论复现行为如何影响科学研究的透明度和可信度。


上一节我们讨论了研究复现的重要性。本节中我们来看看,研究复现这一行为具体由谁来执行。

研究复现要产生实际效果,必须有人采取行动。仅仅发表一篇声称可复现的论文是不够的。只有当有人获取数据和代码,进行检查、重新运行分析,甚至尝试其他方法时,复现才真正发生。

以下是复现研究通常涉及的步骤:

  • 重新运行分析:使用原始数据和代码重复整个分析流程。
  • 检查代码:审查代码逻辑,寻找潜在错误或偏差。
  • 尝试替代方法:使用不同的分析方法或参数来验证结果的稳健性。


那么,这个“有人”是谁?他们的目标是什么?这个问题至关重要。

根据我的理解,可能想要复现你研究的人大致可以分为三类。假设你作为原始研究者,声称真相是 A

以下是三类潜在的复现者:

  1. 普通公众:这是最大的人群。他们通常不关心具体的科学细节。
  2. 其他科学家:这部分科学家可能同意你的观点(认为真相是 A),也可能持有不同假设(认为真相是 B)。他们通常有自己关于世界如何运作的假设。
  3. 持反对意见者:这部分人认为真相并非你所说的那样。他们没有一个具体的世界运作模型,只是单纯地想证明你的结论是错的。

图中方框的大小大致代表了该群体中的人复现你工作的可能性。

科学家群体有可能进行复现,但他们通常忙于自己的研究。而持反对意见者则对你的工作复现非常感兴趣。幸运的是,我的工作大部分都是可复现的。但必须承认,这类复现有可能给你的个人工作带来困扰。


到目前为止,我的思考是:研究复现带来了透明度,这至关重要。它也促进了知识传递。关于如何促使人们分享数据的讨论很多,数据共享显然是可复现性的关键。

但我认为,“我们能否信任所见到的分析”这个核心问题,并未被可复现性从根本上解决。此外,复现是一种非常下游的活动,许多这类二次分析都受到他人兴趣和动机的影响,其中也包括我自己的主观色彩。

这引向了我称之为 “基于证据的数据分析” 的理念。


我认为真正的数据分析涉及将大量工具和方法串联起来,形成一个长长的处理流程。很多时候,方法是标准的——对于流程的某个特定环节,每个人都会做同样的事。有时则没有标准,你可以按自己的想法进行。

基本想法是,我们应该使用经过充分研究、科学界(或子领域)公认的合适方法。我们不必追求完美,但应努力实现一个 85% 的解决方案

同时,应该有证据来证明特定方法的应用是合理的。作为统计学家,我们一直在做这件事:通过模拟、理论等方式比较不同方法,以确定在给定情况下哪种方法更合适。


举一个非常简单的例子。这是我在 R 语言中生成的一个直方图,我仅仅输入了 hist(x)。直方图本质上是一种平滑器,而平滑器中最重要的参数就是带宽。我什么都没做就生成了这个直方图,那么带宽是如何被选定的呢?

原来,Sturges 在 1926 年发表了一篇论文(“发表”这个词用得很宽泛,那更像是一封长信),他提出了一个选择分组数的公式。后来,当核平滑方法流行起来时,David Scott 在《Biometrika》上发表了一篇论文,讨论了基于积分均方误差等度量来选择带宽。

无论如何,默认的带宽就这样被编程进了软件。大部分时候,没有人对此提出异议。有时我们会调大或调小它,这没问题。但通常默认值就相当不错,而且这个默认值背后确实有一些研究作为支撑。


本节课中我们一起学习了:

  1. 研究复现需要由具体的个人或群体来执行,而不仅仅是宣称。
  2. 潜在的复现者主要分为三类:普通公众、其他科学家和持反对意见者,他们的动机各不相同。
  3. 研究复现能提高透明度和促进知识传递,但并不能完全解决分析结果的可信度问题。
  4. 我们引入了 “基于证据的数据分析” 概念,强调应使用经过充分研究且有证据支持的标准化方法。
  5. 通过直方图带宽选择的例子,我们看到了默认参数背后往往存在历史研究依据。

理解谁在进行复现以及为何复现,有助于我们更好地设计研究、分享数据与代码,最终推动更可靠、更透明的科学研究。

在本节课中,我们将学习“基于证据的数据分析”的核心思想,即如何构建标准化的、确定性的分析流程,并将其应用于科学研究中,以提高分析结果的可信度和可重复性。


我的核心观点是,我们应该将这一原则尽可能地应用到所有地方。

我们应尽可能使用基于证据的组件来创建分析流程,并将其标准化。

杰夫对此的另一个贡献是,他将此称为“确定性统计机器”。其核心思想是,你拥有一个算法或流程,在给定一组数据和最少的输入参数时,能够产生确定性的结果。

一旦这个基于证据的流程被建立,你就不要再去改动它。我称之为“透明盒子分析”。它是一个盒子,所以你不去动它,就像阿尔·戈尔的“锁箱”一样。但它是透明的,因为你可以清楚地知道里面发生了什么。所以它不是一个黑盒,你能看到过程,但关键是你不要去干预。

这样做的一个目标是减少所谓的“研究自由度”,即研究人员可以调整整个流程中的每一个调优参数,这种可能性呈指数级增长,从而可能从分析中得到任何他们想要的结果。

我认为这类似于一个理想的、预先设定的临床试验方案。当你进行临床试验时,你必须事先说明你将要做的一切,包括如何分析数据。如果有人已经为你写好了这个方案,那该多好?如果你使用一个标准化的流程,并且有人已经为你写好了,你就可以为特定情况预先精确指定你要做的事情。

其基本结构只是一个示意图,当然具体取决于你实际要解决的问题。你有一些数据集,可能还有一些最少的元数据输入,然后数据会经过一系列模块,这些模块可能很长,涉及预处理和各种统计方法。你可以想象,会有一组基准数据集或数据,用于评估各种类型的统计方法。

最终,你可以生成某种报告,或许可以复制粘贴到论文的方法部分,或者发布在某个公共存储库中。

我想通过一个快速案例研究来说明我的意思。我经常做的一件事是研究空气污染暴露的急性健康效应。这些是相关性研究,很多工作起源于七八十年代,所以我们有很长的研究历史。基本问题是:污染的短期变化是否与人群健康结果的短期变化相关?

这类研究通常在社区层面进行,并且有很多统计研究投入其中,其中一部分是我自己完成的。这是数据通常的样子:你有死亡计数(例如纽约市),持续几年;然后底部是颗粒物水平。你可以看到颗粒物数据没有死亡率数据那么多,因为有很多缺失数据。基本上,你只是想问:顶部这个(死亡率)和底部这个(污染)相关吗?

问题是,我们能否将我们在统计和流行病学研究中发现的所有东西编码到一个单一的软件包中?答案是肯定的。像这样的时间序列研究没有巨大的变化范围,通常涉及相似类型的数据(可能是住院、死亡率等),往往非常相似。那么我们能否在这个领域创建一个确定性的统计机器呢?

基本的流程非常简单,分析本身并不复杂。你需要检查数据中是否有异常值或高杠杆点。污染数据通常是偏态的,所以你需要检查这一点。对于过度离散,你需要检查。你想填补缺失数据吗?答案绝对是“不”。已有大量研究表明,这样做效果不好。这里的大问题实际上是模型选择。

在这些时间序列研究中,我们必须担心未测量的混杂因素。我们没有测量很多随时间变化的东西,这就像你的批次效应。因此,你必须使用各种方法来估计如何调整这些未测量的混杂因素,通常使用半参数回归方法。所以,估计自由度对任何你可能估计的关联都有最深远的影响,这至关重要。实际上,有关于如何做这件事的研究,有几篇论文(其中一篇是我的),有各种估计这个自由度数量的方法。我们可以选择一两种比其他方法更好的方法并实现它。模型的其他方面往往不那么重要,比如你是否调整温度,以及如何调整,通常影响不大。你通常还对多重滞后分析和敏感性分析感兴趣。你可以在这里选择一个模型,但你想看看如果你稍微前后移动模型,你的关联是否会急剧变化。这些是这类分析中你通常想看到的东西,当我每月审阅一篇时间序列研究的论文时,我总是会问这些问题。

关于为什么在这种背景下填补数据如此糟糕的15秒回答是:因为数据是系统性缺失的。污染数据很难收集,通常每六天才测量一次,所以每六天就有五天数据缺失。你可以尝试填补它,但你只是用大量的噪音换取了一点点的节省,并且可能引入偏差。

我认为,显然数据分析有很多领域,不同问题需要不同的专业知识,我不可能处理所有事情。但核心思想是,你可以创建一个由这些“机器”组成的精选库,提供标准化的、最先进的分析流程。显然,不同领域有不同的会议。污染的时间序列分析是一个非常成熟的领域,目前没有很多统计研究在进行,很多问题已经解决。因此,我们可以建立一个这类数据分析的档案库。

一个类似的例子是Cochrane协作网,它是一个基于证据的医学档案库。你可以去Cochrane协作网搜索诸如“阿司匹林治疗头痛”之类的东西。例如,你可以搜索“能否使用维生素C治疗哮喘”,这里有一个总结说:我们审查了证据,他们基本上做了荟萃分析,审查了来自9个维生素C临床试验的证据。总的来说,这些试验规模很小,既不能推荐使用也不能推荐避免使用维生素C治疗哮喘。所以,我们不用担心维生素C,它不会帮助我们,但也不会伤害我们。这构成了许多基于证据的干预和治疗的基础。类似的事情也可以为数据分析而做。

我们可以拥有由该领域知识渊博的专家策划的、编码了数据分析流程的软件包。这些不必是完美的解决方案,但想法是它们应该是相当好的解决方案,能够覆盖大部分基础。


这就是我想说的全部内容。我做了一个基础介绍,虽然我没有真正谈论可重复研究,但我确实认为它很重要。然而,我认为它并没有从根本上解决你是否能信任一个分析这个最重要的问题。因此,我称之为“基于证据的数据分析”。我知道有些人不喜欢这个短语,但其核心思想是为特定的科学领域和问题制定有组织的、标准化的**实践。我并不是说它们不存在,真正的问题在于组织和整合。

我认为这可以为审稿人提供一个强大的工具,而不会像要求他们重现分析那样极大地增加他们的负担。我认为我们应该投入更多精力来解决科学研究的上游方面问题。


本节课总结

本节课中,我们一起学习了“基于证据的数据分析”理念。我们探讨了如何构建“确定性统计机器”或“透明盒子”分析流程,以减少研究自由度并提高结果的可信度。通过一个空气污染时间序列研究的案例,我们看到了将成熟的研究方法标准化为可重复流程的可能性。最后,我们讨论了建立类似“Cochrane协作网”的数据分析**实践档案库的愿景,以促进科学研究的严谨性和可靠性。

在本节课中,我们将学习“可重复研究”中的一个核心概念:缓存计算。我们将探讨如何通过“文学化统计编程”的理念,将分析代码、数据和文档整合在一起,并利用缓存技术来提高分析的可重复性和分享效率。


上一节我们介绍了可重复研究的基础。本节中,我们来看看如何将研究与文档更紧密地结合。

文学化统计编程的理念源于文学化编程。其核心思想是将一篇文章视为文本和代码的混合流。分析代码负责处理数据,这些代码以“代码块”的形式存在。此外,还有用于格式化结果的呈现代码。文本则穿插其中,用于解释正在进行的操作。

这些文学化统计程序可以被“编织”以生成人类可读的文档,或被“缠结”以生成机器可读的文档。这个概念最初由Donald Knuth提出。

文学化编程概念需要两个要素:一个文档语言和一个编程语言。

在R统计分析环境中,有一个名为Sweave的特定包。它使用LaTeX作为其文档语言,R作为其编程语言,由Friedrich Leisch开发。当然,也存在其他可用的组合。


上一节我们了解了文学化编程。本节中,我们来看看如何将研究的各个部分存储并分享。

我们的目标是将分析数据、计算代码和分析代码整合起来。具体过程是:文章本身(例如发表在期刊上)是可获取的,我们也让生成文章的分析过程变得可获取。

其理念是将这些内容存储在某种数据库中,使其对读者可用。读者希望从文章入手,深入探究;而作者则是从数据出发,最终生成文章。

以下是实现这一理念的步骤:

  1. 在文学化统计程序框架中,你的论文包含文本和代码。
  2. 代码块对数据进行操作。
  3. 代码块的结果被存储在某个数据库中。
  4. 你最终发布论文时,也一同发布这个数据库部分。
  5. 论文中的图表和表格,就是从数据库中存储的材料生成的。

上一节我们讨论了分享研究数据库的构想。本节中,我们来看看实现这一构想的具体工具。

我们开发了两个包:一个是与S语言交互的CacheS(本次不讨论),另一个是独立的CacheR包。

其基本假设是,你有一个包含代码的R文件。该包会读取你的代码,评估它,并将结果存储在一个键值数据库中。每个代码表达式都会被赋予一个SHA1哈希值,以便跟踪任何更改并在必要时重新评估。

其理念是,你可以将代码和数据打包成一个“缓存包”分发给他人。其他人可以克隆这个分析,查看代码子集或检查特定的数据对象。这里的一个重要假设是,其他人可能没有与你相同的计算资源,他们可能不想运行整个耗时的马尔可夫链蒙特卡洛模拟,而只想查看特定的最终结果。这种方式允许他们像剥洋葱一样层层深入,而不是直接触及核心。

基本模型是:你有一个源代码文件,代码和数据作为输入,产生结果。

作为作者,缓存包的工作流程如下:

  1. 它解析源文件。
  2. 它创建用于存储内容的目录和子目录。
  3. 它评估每个表达式。如果一个表达式没有改变,再次运行时它不会重新执行,而是直接从数据库加载结果。
  4. 它为每个表达式写出一堆元数据。
  5. 一旦你评估了整个分析(这可能耗时很长),所有中间结果都存储在数据库中。
  6. 你可以将其打包成一个可分发的包(本质上是一个zip文件)。

以下是一个简单分析的例子:

library(datasets) data(airquality) fit <- lm(Ozone ~ Wind + Temp + Solar.R, data = airquality) summary(fit) plot(fit) 

任何创建了变量的表达式,其结果都会被存储在数据库中。如果一个表达式只是向控制台打印内容,则不会存储。图形本身不会被存储,但生成图形的代码和结果会被记录。

生成的包会有一个标识符(如SHA1哈希值)。在文章中,你可以说明文章中的所有内容都可以在这个包中找到,并给出标识字符串。通常,使用前四个字符就足以唯一标识该包。


上一节我们从作者角度了解了如何创建缓存包。本节中,我们切换到读者视角,看看如何使用和验证这些包。

作为读者,如果你在期刊上看到这样的文章,你可以获取那个标识字符串(例如前四个字符),然后克隆整个分析包。克隆后,本地会创建一些目录,源代码文件和元数据会被下载。

但数据本身默认不会立即下载,因为它们可能很大。不过,对已创建的各种数据对象的引用会被加载。这些引用是“惰性加载”到环境中的,只有当你想要查看某个对象时,它才会被下载到你的计算机上。

你可以查看代码,甚至可以生成代码的图形化概览。这个图形会展示分析中所有数据对象是如何组合在一起的。例如,变量A、B和C共同创建了数据集D,然后数据集D与某个函数结合生成了估计值,等等。

如果你对某个特定数据对象感兴趣,你可以使用objectCode函数。它会显示生成该对象所涉及的具体代码行(可能只是整个文件中的一部分)。

你还可以使用runCode函数执行代码。默认情况下,它不会从头执行所有计算,而是从数据库加载对象以使过程更快。当然,你也可以强制它从头运行所有计算。

重要的是,checkCode函数会从头评估所有表达式,不加载数据库中的任何内容。然后,它会将评估结果与存储的结果进行比对检查(通过检查对象的“签名”是否匹配)。为了实现这一点,你需要设置随机数生成器的种子等参数。

此外,还有一个辅助函数可以检查每个单独的数据对象,查看是否有损坏(基本上就是检查签名)。

使用loadCache函数,你可以加载指向特定数据对象的指针(这些对象可能存储在服务器上)。每当你访问该对象(例如打印到屏幕或绘图)时,它才会从存储位置传输过来。一旦加载到你的系统中,后续访问就无需再次传输。


本节课中,我们一起学习了缓存计算在可重复研究中的应用。

我们首先介绍了文学化统计编程的理念,它将代码、数据和解释性文本融为一体。接着,我们探讨了如何构建一个可分享的研究数据库,将分析过程与最终论文一同发布。

然后,我们深入了解了CacheR包的工作原理。从作者视角,它通过缓存中间结果、跟踪代码更改,将整个分析打包成一个可分发的单元。从读者视角,它允许用户克隆分析、按需探索特定对象或代码,而无需耗费大量资源重新运行整个复杂分析。

最后,我们看到了读者如何使用工具来探索和验证缓存的分析,例如查看代码依赖图、检查生成特定对象的代码,以及验证结果的完整性。

这个包的基本目标是: mindful of readers' resources(体谅读者的资源),并高效地仅加载所需内容,从而在保持分析完整性和深度的同时,降低分享和复现的门槛。

在本节课中,我们将通过一个关于空气污染的真实案例研究,来探讨可重复研究的重要性。我们将了解如何识别细颗粒物(PM)中的有害化学成分,并分析一项关键研究如何因其数据的公开性而促进了科学的讨论与进步。

细颗粒物(PM)并非单一物质,而是由多种不同化学成分组成的复杂混合物。你可以将其想象成吸入的“灰尘”,但这“灰尘”包含金属、盐类等多种物质。一个重要的科学假设是:其中某些成分比其他成分更有害。如果能够识别出这些有害成分,我们就能更有针对性地管控其排放源,从而更有效地保护公众健康。

目前,对PM的监管主要基于其总质量浓度,而不区分其具体化学成分或来源。这种策略虽然有益于公共健康,但可能并非最高效的。

为了深入探究PM的健康影响,我们聚焦于一项名为“国家发病率、死亡率和空气污染研究”(NMMAPS)的项目。这是一项全国性研究,旨在评估环境空气污染(特别是PM10和臭氧)的短期健康效应。

以下是该研究的关键信息:

  • 健康结局:研究关注全因死亡率,以及心血管和呼吸系统疾病的住院率。
  • 数据公开性:NMMAPS是可重复性最高的空气污染研究之一。研究者通过“基于互联网的健康与空气污染监测系统”(IHAPSS)网站,公开了所有空气污染数据、气象数据、软件代码和结果。
  • 研究影响:自数据公开以来,已催生了超过67篇独立于原始NMMAPS的后续研究论文,使其成为该领域方法学发展的重要测试平台。

基于NMMAPS的公开数据,后续研究取得了一项引人注目的发现。一篇发表在《环境健康展望》期刊上的论文指出,(PM中常见的一种过渡金属)可能显著改变PM10在美国60个社区中的短期健康风险。

具体结论是:在PM中浓度相对较高的社区,PM10带来的健康风险也更大。这暗示镍可能是PM中有害的关键成分之一,而其他成分(如硫酸盐)则未表现出类似的“效应修饰”作用。这个结果很有吸引力,因为它似乎指出了一个明确的调控靶点。

然而,科学需要质疑与验证。我们(包括Francesca Dominici及其同事)决定重新分析数据,以探究这种关联的稳健性。我们注意到,美国纽约市的镍浓度远高于其他地区。

我们绘制了散点图,其中X轴是社区的长期平均镍浓度,Y轴是PM导致的死亡率风险升高百分比。图中显示,两者似乎存在正相关关系。

核心分析步骤

  1. 拟合一条简单的线性回归线,其公式可表示为:风险 = β₀ + β₁ * 镍浓度。初始分析显示斜率(β₁)为正且具有统计学意义(P值 < 0.01)。
  2. 然而,散点图最右侧存在几个明显的高杠杆点,它们全部来自纽约市的县区。
  3. 当我们移除纽约市的数据点后重新拟合回归线,新的斜率(蓝色线)不再具有统计学意义(P值 ≈ 0.31)。

这个简单的敏感性分析表明,最初的显著关联很大程度上依赖于纽约市这几个异常高的数据点。

为了更系统地评估结果的稳健性,我们进行了“逐一剔除”分析。

以下是分析过程:

  • 我们依次从60个社区的数据中移除一个社区,然后重新计算回归线的斜率。
  • 结果显示,移除绝大多数社区时,斜率估计值(图中黑点)都聚集在相似范围内。
  • 但是,当移除整个纽约市的数据时(图中红点),斜率估计值大幅下降,置信区间也明显变宽。

这再次证明,整个分析结论对单一城市(纽约市)的数据异常敏感。

通过这次再分析,我们确认了以下几点:

  1. 纽约市的镍和钒浓度确实远高于美国其他社区。
  2. 即使排除纽约市数据,镍浓度与PM健康风险之间仍存在正相关关系。
  3. 然而,这种关联的证据强度因对少数数据点高度敏感而受到削弱。最初的证据可能没有看起来那么强有力。

这项再分析并未完全否定“镍有害”的假设,但指出需要更多研究来稳健地验证这一假设。

这个案例完美诠释了可重复研究的价值:

  1. 促进新假设探索:NMMAPS数据的公开,使得Liman等人的研究能够提出并验证“镍是PM有害成分”这一新假设。
  2. 允许批判与验证:数据的可获取性,使得我们(Dominici等人)能够对前述研究进行批判性再分析,评估其证据的稳健性。
  3. 推动科学进程:整个过程中,所有研究者基于相同的数据进行透明的分析、辩论和验证。好的想法得以浮现,薄弱的证据被指出,科学得以在充分信息交流中向前发展。可重复性使得整个科学讨论更加明智和及时

本节课中,我们一起学习了一个关于空气污染成分研究的完整案例。我们了解到细颗粒物(PM)成分的复杂性,回顾了具有高度可重复性的NMMAPS研究及其公开数据平台。我们深入分析了一项关于镍的关键研究,并通过敏感性分析发现其结论对异常值(纽约市)高度敏感。最后,我们总结了可重复研究如何通过促进数据共享、允许重复分析和批判性讨论,来推动科学知识的稳健积累与进步。这正是可重复研究的核心价值所在。

在本节课中,我们将通过一个发生在杜克大学研究人员身上的真实案例,探讨高通量生物学研究中可重复性的重要性。这个案例涉及使用基因组特征来预测癌症患者对化疗药物的反应。我们将看到,由于分析过程中的一系列错误和文档记录的缺失,导致了一项看似前景广阔的研究最终引发了严重的临床问题。通过剖析这个案例,我们可以学习到确保研究可重复性的关键教训。


上一节我们介绍了可重复研究的基本概念。本节中,我们来看看为什么在高通量生物学领域,这一点尤为关键。

随着我们能够进行越来越精密的检测并生成成千上万的测量数据,分析工作占据了研究过程中越来越大的比重。因此,不仅我们自己,其他人也应该能够精确地复现我们的工作。这意味着,如果他人从相同的数据出发,应该能得到相同的结果。

在高通量生物学中,这一点之所以特别重要,还有一个不同的原因:我们对于高通量生物学中“什么是有意义的”直觉往往非常不可靠。临床医生可能对单个基因的行为有深刻直觉,但面对一个包含100个基因的特征列表时,他们同样可能从随机列表中“发现”模式。因此,我们不能依赖直觉来验证结果的合理性,而必须依赖清晰、可复现的分析流程。

遗憾的是,当我们查阅文献并试图理解一篇典型论文中做了什么时,文档记录往往非常糟糕。如果一项发现很重要但文档记录很差,我们有时不得不进行“法医生物信息学”,即从结果和原始数据出发,反向推导研究者到底做了什么,而不论其方法部分如何描述。


以下我们将深入分析一个具体的临床案例,该案例旨在使用基因组特征预测化疗敏感性。

这项研究基于2006年底发表在《自然·医学》上的一篇论文。研究者声称,他们从细胞系出发,找到了一种方法,可以得出对多种药物的基因组敏感性特征。

他们的工作流程如下:

  1. 使用美国国家癌症研究所的标准细胞系面板NCI-60。
  2. 针对目标药物,找出最敏感和最耐药的细胞系。
  3. 对这些细胞系进行芯片分析,对比两组,找出差异最大的基因。
  4. 使用“元基因”(即主成分分析)方法,用这些基因构建敏感性特征模型。
  5. 将该模型应用于临床样本数据进行预测。

他们用多个公共数据集和七种常用药物进行了测试,并报告了出色的结果。论文发表后,很快就有多个研究小组希望复现并应用该方法。


当我们尝试复现这项研究时,首先选择了药物“多西他赛”作为起点。

我们使用NCI-60细胞系的U95A芯片数据,选取了最敏感和最耐药的细胞系。在训练数据中,我们看到了预期的分离效果:耐药细胞系在主成分分析图中集中在左侧,敏感细胞系集中在右侧。

然而,当我们把该模型应用到真实的患者数据上时,并未看到预期的分离效果。这促使我们怀疑自己是否做错了什么,从而开始仔细追溯原始论文中的分析步骤。

论文的补充材料中提供了每种药物所用到的所有探针组ID列表。我们决定从药物“5-氟尿嘧啶”开始检查。

以下是构建热图时的发现:

  • 论文中展示的热图显示,他们选出的45个基因在两组细胞系中呈现出完美的、相反的表达模式。
  • 我们使用同样的t检验方法,选出了我们自己的45个**基因。
  • 当我们用论文中提供的探针ID列表生成热图时,结果却不符合预期。

于是,我们将他们的列表与我们的列表并排比较,发现了一个明显的规律:他们的每个探针ID都比正确的ID大1。这是一个典型的“索引偏移一位”错误。


这个索引错误是如何产生的?通过检查他们使用的软件,我们发现了原因。

他们的软件需要两个输入文件:

  1. 定量矩阵:行为基因,列为样本。首行是标题行,用0、1或2来标识该样本是敏感训练样本、耐药训练样本还是待预测的测试样本。
  2. 基因ID列表:其顺序必须与定量矩阵中的基因顺序完全一致,但这个文件不能有标题行

如果用户从一个有标题行的Excel文件中复制基因列表,就会不小心把标题也粘贴进去,导致所有基因ID向下偏移一位。我们用“多西他赛”的数据测试了这个假设,完美地复现了论文中的热图。

我们对论文中涉及的七种药物都进行了检查:

  • 拓扑替康、依托泊苷、5-氟尿嘧啶、紫杉醇、多西他赛:大部分存在“偏移一位”错误。
  • 阿霉素:大部分存在“偏移一位”错误,但还有少数基因无法解释。
  • 环磷酰胺:完全无法理解他们用了哪些基因。

至此,我们发现了第一个严重问题:论文中用于解释生物学机制的基因,实际上可能根本不在他们分析所用的基因列表中。


除了基因列表错误,我们在检查他们的预测结果时发现了更致命的问题。

以药物“多西他赛”为例,论文中的图表显示有13个敏感样本和11个耐药样本。然而,提供该测试数据集的原始论文明确指出,他们有11个敏感样本和13个耐药样本。样本标签的数量对不上。

更严重的问题出现在药物“阿霉素”上。在他们的结果图中,显示为耐药的样本(红色三角)远多于敏感样本(蓝色方块)。然而,该数据集来源于一篇关于儿童白血病的论文,而儿童白血病的治愈率高达80%。如果大多数患者都对一种药物耐药,临床上根本不会使用它。原始数据提交者也认为大多数患者是敏感的。

我们怀疑,他们在准备数据时,将标签“0”和“1”的含义弄反了(即敏感和耐药互换),而自己并未察觉。这在临床上是灾难性的,因为这意味着他们会根据这个特征,只对那些实际上不会受益的患者使用阿霉素。


一个随之而来的问题是:如果他们的数据标签如此混乱,当初是如何得到“良好”的预测结果的?

这引出了我们之前忽略的另一个问题:对于那些无法用“偏移一位”错误解释的基因,它们从何而来?以“多西他赛”为例,有19个这样的基因。

我们发现,其中14个基因恰好连续地出现在提供测试数据的原始论文所报告的“能区分敏感和耐药的92个基因”列表中。从92个基因中随机抽取14个,它们恰好连续出现的概率极低。这强烈暗示,他们在构建特征时,可能有意或无意地参考了测试集的信息,这是一种严重的“数据窥探”错误,会极大地夸大预测效果。

剩下的5个无法解释的基因,恰恰是论文中专门点名、用于解释特征生物学意义的基因。因此,对于多西他赛的特征,区分训练集的基因、区分测试集的基因和解释机制的基因,三者毫无重叠。这令人非常不安。


我们将这些发现写成信件投给《自然·医学》。我们坚持可重复研究的原则,因此在信件附带的补充材料中提供了全部代码和数据,任何人都可以运行并验证我们的结果。

作者的回应并非承认错误,而是声称我们的分析“存在严重缺陷”,并坚持他们的标签是正确的,因为他们已将方法再次应用于其他数据并取得成功。

我们检查了他们新公布的数据。以阿霉素为例,他们公布了一个包含144个样本的定量矩阵。当我们检查样本间的相关性时,发现了一个奇怪的现象:在122个测试样本中,有些样本被重复使用了3到4次,并且同一个样本被标记为耐药和敏感的次数不一致。这进一步证明他们的标签系统是混乱的。

尽管我们多次指出问题,但杜克大学的研究团队仍在继续发表论文,并基于这些有缺陷的特征启动了临床试验,用以为患者分配治疗方案。这促使我们撰写了一篇详尽的论文,于2010年9月提交,并很快被《应用统计年鉴》接受发表。

论文发表后,经媒体曝光,杜克大学启动了内部调查并暂停了试验。然而,调查在2011年1月结束,杜克大学宣布“加强了他们对这种个性化癌症治疗方法的信心”,并重启了试验。他们拒绝公开调查报告。


我们并未放弃。我们发现,在调查期间,他们又公布了一组用于验证“顺铂”和“培美曲塞”预测效果的新数据(共59个样本)。这两个药物正在临床试验中使用。

我们尝试将这59个样本与原始数据库进行匹配,结果令人震惊:

  • 43个样本的标签完全错误。
  • 剩余16个样本的基因标签混乱到无法识别其对应哪个原始样本。
  • 这意味着,这个用于验证两个已进行两年临床试验的药物的数据集,每一个样本都是错误的。

我们通过《信息自由法案》从美国国家癌症研究所获得了杜克大学的内部调查报告。报告显示,审查委员会自己也无法仅从已发表的数据中复现该研究,他们依赖了未公开的额外信息。此外,报告完全没有提及我们刚刚发现的关于顺铂和培美曲塞数据的严重问题。

最终,在多方压力下,特别是在33位生物统计学家联名致信**后,杜克大学于2011年7月最终暂停了相关临床试验。多项外部调查随之启动。


回顾整个案例,我们可以总结出以下核心教训:

常见错误往往很简单

  • 索引偏移(如Excel复制粘贴错误)。
  • 样本或基因标签混淆。
  • 实验设计完全混淆。

简单错误为何能通过审查?

  • 因为在高通量生物学中,我们的直觉并不可靠,无法一眼看出错误。
  • 如果文档记录(代码、数据标注)不完整、不清晰,这些错误就很难被发现,从而溜进出版物甚至临床实践。

对论文发表的最低要求

  1. 提供数据:在如GEO等公共数据库存放数据。
  2. 清晰标注:提供定量表格时,请标注列名,说明每个样本的身份。
  3. 提供代码:提供分析所用的完整代码。

对临床试验的绝对要求
上述对论文的要求,在开启涉及患者治疗的临床试验之前,必须是绝对的前提条件。




作为对这类事件的回应,自2007年起,我们团队强制推行了以下措施:

  • 使用Sweave:所有分析报告必须使用Sweave(结合R和LaTeX)编写。这样,报告本身包含了生成所有结果和图表的数据与代码,他人可直接运行复现。
  • 双重审核流程:分析报告由分析师撰写,提交给资深研究员审核;研究员在审阅内容的同时,必须重新运行代码以确保结果一致。只有经过这两步,报告才能发送给合作的生物学家。

这种方法极大地提高了我们工作的可重复性和透明度。


本节课中,我们一起学习了“可重复研究”在高通量生物学中的极端重要性。通过杜克大学的案例,我们看到了从简单的索引错误、标签混淆,到严重的数据窥探和临床误用这一连串问题。核心问题在于分析过程缺乏透明度、文档记录不完整以及代码未共享,导致错误无法被及时发现和纠正。

这个案例的教训是深刻的:无论是为了科学的严谨性,还是为了患者的安全,我们都必须将研究的可重复性置于核心地位。提供完整的数据、清晰的元数据以及可执行的代码,不应再是可选项,而应是所有科学研究,尤其是那些可能影响临床决策的研究的必备标准。

在本节课中,我们将学习如何审视和评论数据分析过程。我们将探讨两个核心观点:一是如何将低质量数据分析视为一个需要预防的“问题”,二是如何通过正确界定分析问题来提升研究的可重复性。


上一节我们讨论了数据分析的一般原则,本节中我们来看看针对数据分析过程的具体评论。

近期,我与Jeff Lee在《美国国家科学院院刊》和《科学》杂志上发表了两篇评论文章。

第一篇评论的核心观点是,应将低质量的数据分析视为一个需要被预防的问题。这类似于预防疾病的思路,即我们如何防止“低质量分析”这一问题的发生。这一观点与本课程中已学过的“循证数据分析”讲座紧密相关。我们撰写该文旨在总结我们认为应采取的举措,以及如何最有效地解决这一问题,防止低劣的分析发生并发表在学术文献中。

第二篇近期发表于《科学》杂志的评论,则聚焦于数据分析中问题的界定。如果未能恰当地识别分析问题,将导致可重复性方面的困扰。因为数据分析有多种类型,并非所有类型都要求结果能被完全复现。

以下是不同类型数据分析的简要说明:

  • 探索性分析:这类分析旨在寻找可能有意义的预测变量或模式,为后续更严谨的研究提供假设或思路。它本质上是生成性的,我们并不期望其结果是最终结论。
  • 验证性分析:这类分析基于精心设计的试验或研究,旨在验证特定关联(如两种事物是否相关)或干预效果(如某药物是否能改善特定疾病患者的健康)。此类分析要求极为严谨,通常需要预先制定详细的研究方案。

因此,在评估各类出版物提供的证据时,一个有效的方法是首先识别其提出的问题类型以及所采用的分析类型。这样,我们就能合理设定对分析结果的预期,并判断哪些结果在未来应被复现。

我鼓励大家阅读这两篇评论,并思考其中的观点。


本节课中,我们一起学习了从预防低质量分析和正确定义问题两个角度来评论数据分析。理解分析的目标是探索性的还是验证性的,有助于我们设定合理的预期并评估研究的可重复性。

在本节课中,我们将介绍本周的同行评估任务。本次任务要求你基于美国国家海洋和大气管理局的风暴事件数据库进行一次数据分析。

为了让你更清晰地理解我的思路和期望,我已经撰写了一份示例数据分析报告。你可以在本讲座旁找到该报告的链接,或者访问与本讲座相关的课程网站链接。

上一节我们介绍了评估的基本要求,本节中我们来看看如何获取和分析数据。

以下是获取示例分析报告的步骤:

  • 你可以在本视频讲座的旁边找到示例报告的链接。
  • 你也可以访问课程网站上与本讲座相关联的链接。

本节课中我们一起学习了本周同行评估的任务目标,即使用NOAA风暴数据库进行数据分析,并了解了获取示例分析报告的途径。祝你本周评估顺利,我期待看到大家的成果。

小讯
上一篇 2026-03-28 16:45
下一篇 2026-03-28 16:43

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/247713.html