介绍
我们研发部门的大部分数据来自数据库、Excel 或 CSV 文件,或者直接输入到 JMP 中。但支持数据通常以其他格式提供,最明显的是 PDF 文件。例如,化学参考表、供应商信息表,甚至现在仅以 PDF 形式存在的历史公司数据。这种类型的支持信息对于补充实验数据非常有用,幸运的是,JMP 有一个 PDF 导入向导,可以导入此类数据。由于这些表格不是为 JMP 等统计软件格式化的,因此从 PDF 导入数据通常会导致数据表混乱,有时需要额外的清理步骤。
在我过去的研发工作中,我知道 JMP 中的 PDF 导入向导,有时也会使用它。也有一些情况是,我找到了 PDF 数据来补充我的研究项目,但在将数据导入 JMP 后,我不知道如何清理表格。在这些情况下,我不得不放弃这个项目并放弃额外的信息,这非常令人沮丧。
几年后,我觉得我有工具可以处理任何 PDF 文件,无论导入后数据有多混乱。与许多混乱的数据问题一样,列公式是清理导入的 PDF 数据的方法。在 Workflow Builder 中记录步骤或需要捕获脚本以自动化流程时尤其如此。
谁应该读这个博客?
如果您符合以下条件,请继续阅读:
- 想要了解有关 PDF 导入向导基础知识的更多信息
- 导入 PDF 数据后,数据清理工作陷入困境
- 想要详细了解如何使用标志列和列下标来清理数据
- 想要了解如何在多个页面上循环执行 DPF 清理步骤
请注意,您不必读完所有内容,您可以跳到下面感兴趣的部分。
概述
我发现在清理从 PDF 导入的数据时,我会回到两个构造,我要么单独使用它们,要么组合使用它们。它们是:
- 标记列:创建二进制标记来标识符合特定条件的行。它可以是“缺失与不缺失”、“零”与“非零”等等。标记列还可以与根据条件选择行结合使用。
- 行下标:将一个单元格与下一个单元格(或前一个单元格)进行比较,并使用它来生成标记列或连接连续单元格中的单元格值。使用 Row()、Row() +1、Row()-1 作为列下标(在下标括号“[ ]”之间使用)。
我还有一些经常使用的有用公式。
有用的公式:
- 缺失()
- 包含()
- 如果 ()
- 长度()
- 连接(“||”)
在这篇博文中,我将研究导入 PDF 数据时通常出现的以下类型的问题:
对于每个主题,你会发现一个简短的讨论和一个视频。
在我们研究这些问题以及如何清理它们之前,请记住,在 JMP 中,几乎总是有多种方法可以获得相同的最终结果。但是,我将选择在 Workflow Builder 中记录的解决方案,以使清理步骤可在工作流中重复使用。通常,这意味着我将使用公式列,而不是“更快”的右键单击选项(如果可用)或使用插件选项。以记录每个步骤的方式设置清理步骤允许我在需要完全相同清理步骤的其他数据表上使用工作流。例如,查看最后一个跨越 13 页的 PDF 表示例。将此 PDF 导入 JMP 时,会创建 13 个表。正如您在上一个视频中看到的,我记录了第一个带有公式列的表的清理步骤,然后在 JMP 中循环清理步骤以将它们应用于所有 13 个表(使用 JMP 18 中 Workflow Builder 中的Group with For Each功能完成),这使得清理这 13 个表变得容易!跳转到此处查看包含工作流生成器循环示例的视频。
让我们从一个简单的例子开始。如果您不熟悉 JMP 中的 PDF 导入向导,请先观看此视频,了解我如何使用导入向导将数据导入 JMP 此 PDF。
问题 1:由于 PDF 中合并的行标题导致缺少单元格值。
PDF 文件中的表格通常被格式化为合并了几行并包含单个值(例如子标题)。导入 JMP 后,表格中出现空行,而不是为包含数据的每一行重复值(图 1)。
Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).Figure 1: Missing cell values in JMP (right side of image) due to merged row subheaders (left side of image).图 1:由于合并行子标题(图像左侧),导致 JMP 中的单元格值缺失(图像右侧)。
清理工作的一个快速解决方案是选择具有缺失值的列(例如,图 1 中的第 3 列),然后右键单击单元格并选择填充,然后选择用上一个值替换缺失值。在 JMP 18 之前的所有 JMP 版本中,此右键单击操作尚未记录在 Workflow Builder 或高级日志中。它将在 JMP 19 中添加,但对于早期版本,使用 Workflow Builder 或高级日志中记录的上一个值替换缺失单元格值的更可靠选项是使用列公式。我使用了一个列公式,如果第 3 列不缺失,则在公式本身中分配一个名为“var”的变量,然后将该值用作下一个缺失值(图 2)。此方法非常适合替换以前的值,因为列公式是从上到下执行的。换句话说,每当第 3 列中有值时,变量“var”就会更新,更新后的值将用于后续行,直到非缺失行发生新的更新。
Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula.Figure 2: Replacing missing with previous value column formula.图 2:用先前的值列公式替换缺失值。
在下一个视频中观看我演示此步骤:
问题 2a:单元格值分散在多行上
PDF 表中需要在 JMP 中清理的合并行的另一个示例是,当某个值(例如子标题)被拆分为同一列中的几行(图 3)。
Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).Figure 3: A cell value, in this case a category subheader (left), is split over multiple rows on import to JMP (right).图 3:单元格值(本例中为类别子标题(左))在导入到 JMP 时被分成多行(右)。
为了清理这个问题,必须识别字符串的各个部分,然后将这些部分串在一起。必须对相应的行重复整个字符串,然后删除剩余的部分字符串。解决此问题的一种方法是创建一个 Flag 列,用于标识缺失与非缺失,或标识“下一行缺失”与“下一行不缺失”。对于图 3 中的示例,以下是可能的步骤顺序(所有步骤都显示在图 4 中):
- 使用标志列识别包含文本的行和不包含文本的行(步骤 1)。
- 使用标志列和带有行下标的公式来识别包含文本的行并与下一行中的文本连接(步骤 2)。
- 一旦有了包含完整字符串的单元格,就创建一个标志列来标识包含部分文本字符串的行并删除这些部分字符串(步骤 3 和 4)。
用整个字符串替换空单元格的缺失值(参见问题 1 的解决方案)。
在图 3 的示例中,我使用了图 4 所示的公式。
Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.Figure 4: Series of column formulas to find and correct a subheader split over two rows.图 4:用于查找和更正分成两行的子标题的一系列列公式。
您可以看到我在这里演示以下步骤:
问题 2b:单元格值分散在多个列中
对于下一个示例,我使用了不同的 PDF 文件,该文件是我在这里找到的。在这种情况下,单元格值分为两行和两列。请看图 5 中的左侧图片。在此示例中,化学名称“Oxy-1,4-phenylenesulfonyl-1,4-phenyleneoxy-1,4-phenelyneisopropylidene-1,4-phenylene”(由蓝色框表示)不仅分为两行,而且分为两列。发生这种情况的原因是,在表格中较高位置列出了两个玻璃化转变 Tg 值而不是一个,使得列分隔符无法避免切断化学名称或 Tg 值(参见红色垂直列分隔符)。
Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.Figure 5: Thermal Transitions table demonstrating a cell value that is split over multiple columns and rows.图 5:热转变表展示了分布在多列和多行上的单元格值。
(来源: https
/www3.nd.edu/~hgao/thermal_transitions_of_homopolymers.pdf)
放置列分隔符后,如图 5 左图所示,Tg 列中有两个单元格包含属于重复单元列的截断文本。在这种情况下,我们可以利用截断文本是字母而不是其他单元格中的数字这一事实。因此,纠正此问题的一种方法是按照以下步骤操作,如图 6 所示:
- 创建一个包含第一个字符的列(步骤 1)。
- 使用 Recode 平台的替换字符串选项将所有数字替换为空。为此,我使用正则表达式 [0-9-] 查找包含“-”的所有数字。(第 2 步)。
- 使用“Ismissing”公式定位文本字符串并将其与原始(截止)字符串连接(步骤 3)。
- 使用条件语句和文本标志列清理 Tg 列。虽然这种方法有点笨拙,但确实有效。如果您知道正则表达式,也可以在列选项 Recode 下使用它。我使用了图 7 中显示的条件语句。
经过所有这些清理工作后,我确定了单元格内容在垂直方向上被拆分成两行的位置:第 39/40 行、第 41/42 行和第 43/44 行。拆分的单元格的字符串第一部分以“-”结尾,因此可以将其用作指示符。接下来,可以使用如图 4 所示的公式构造将文本字符串相加。最后,可以删除空数据单元格以避免出现重复行。
Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.Figure 6: Finding and concatenating split text strings.图6:查找并连接分割的文本字符串。
Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.Figure 7: Removing text string from numbers column.图 7:从数字列中删除文本字符串。
下一个视频展示了我如何使用这些步骤,以便您可以看到该问题的一个可能的解决方案。
问题 3:带有标题或副标题的行与数据混合在一起
对于最后一个例子,我回到列出脂肪脂肪酸组成的 PDF。在这种情况下,您可以看到数据表包含带有标题、单位或子标题的行,在导入 JMP 后,这些行现在与数据混合在一起(图 8)。
识别此类行的一种方法是使用“Contains”公式来识别标题/单元行中实际数据中未找到的符号或文本字符串。例如,在图 8 中,我们使用公式“Contains(“%”)”。如果此符号未出现在单元格中或字符串中字符的实际位置(导致整数 > 0),则此公式将导致“0”。使用简单的条件语句,可以生成一个 Flag 列。
对于此示例,图 9 中显示了一个可能的公式。要删除带有“1”(表示存在“%”)的行,请使用“行/行选择”菜单中的“选择哪里”选项选择符合此条件的行(图 10)。接下来,删除选定的行。高级日志和工作流生成器会捕获此步骤序列,并可以自动执行以供重复使用。请注意,“选择哪里”菜单下直接可用的选择条件有限,包括“包含”,因此您可以直接设置它并放弃“标志”列。
Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.Figure 8: Rows with headers or subheaders are mixed in with the data and appear as rows in the JMP table.图 8:带有标题或副标题的行与数据混合在一起,并作为行出现在 JMP 表中。
Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.Figure 9: Conditional statement with "Contains" formula to create a Flag column that identifies if the "%" character is present.图 9:带有“包含”公式的条件语句创建一个标志列,用于标识是否存在“%”字符。
Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.Figure 10: Adding conditional row selection criteria using a Flag column.图 10:使用标志列添加条件行选择标准。
在此视频中,您可以看到用于识别和删除数据表中不需要的行(在本例中为子标题行)的清理步骤。
奖励视频:使用 WorkflowBuilder 循环导入示例
在此视频中,您可以看到只需单击几下即可将第一页执行的所有清理步骤应用于第二页。我使用 Workflow Builder 中的“Group with For Each”循环来处理上述讨论中显示的 fat.pdf 示例。接下来,我将演示一个更极端的情况,其中我有 13 页宽表格式。每页都必须单独导入并进行清理。但是,一旦我使用 PDF 导入向导从每个页面导入表格,我就可以简单地记录一个表格的清理步骤。然后我可以使用 Workflow Builder 中的“Group with For Each”选项自动对其他 12 个表格运行清理步骤!这有多高效!?!
最后,我 100% 确信有一些更短或更简洁的方法来解决其中一些我尚不知道的问题……欢迎在下面的评论中分享其他解决方案。