大家好。欢迎收看本次关于如何使用点击操作和基本代码破解技巧导入复杂数据的演示。今天和我一起的是我的同事Wendy Tseng。我们都是JMP的系统工程师。我是Monique Roerdink Lander。
我们将讨论如何导入复杂的数据,这源于我在研发部门工作时遇到的一些挑战。今天我们将讨论三个例子,它们都与导入多个数据有关,例如从网站导入多个图像、多个数据表或多个PDF页面。
这些都是比较复杂的数据源,它们可能用于增强现有数据或其他类型的数据,例如实验数据。当我遇到这些挑战时,我最初并不精通脚本编写。为了应对这些挑战,我后来学习了脚本编写,但并非每个人都有时间和兴趣去学习JSL。
这意味着高效导入此类数据可能比较困难,您甚至可能因为无法投入时间而放弃。但其实不必如此,尤其是在 JMP 17 中引入了工作流构建器,并在 JMP 18 中添加了更多重要扩展功能之后。
今天,我们将演示如何自动导入这类数据。我们将使用 Workflow Builder,并且不会使用代码,而是直接使用 JSL。我们会进行一些 JSL 解码,或者我们称之为代码破解。我们假设您对 Workflow Builder 有一定的了解,如果您不了解,我们将直接深入讲解。今天我们有三个示例。在第一个示例中,我的同事 Wendy 将讲解如何自动将图片导入数据表。
这是我必须做的事。而且要做很多。我之前从事洗涤剂配方研发工作,经常需要对眼镜进行磨损和洗涤测试,结果会拍下数百张眼镜的照片。我想把这些照片导入我的数据表,以便与图像分析数据关联起来。
对我来说,当时这确实很棘手。Wendy 将会向我们展示如何高效地完成这项工作。在第一个例子之后,在第二个例子中,我将讲解如何更高效地从 PDF 文件导入数据以及进行必要的清理步骤。最后,Wendy 将讲解如何从网站导入数据。那么,现在就交给 Wendy 吧。
谢谢,莫妮克。在第一个例子中,我将向您展示如何引入图像来增强您对数据的理解和沟通。我们来看看我们要讨论的内容。这次我们不看眼镜,而是看狗的图片。
您眼前看到的这个数据集包含狗狗的照片,照片列在其中。这里有28行,对应28张狗狗的照片。这些照片已与美国养犬俱乐部公开的数据集整合在一起,该数据集包含关于狗狗的不同信息,例如梳理频率和掉毛情况。
接下来我们要看的是它们的性情。这里有一张图表,展示了狗狗的受欢迎程度与性情之间的关系。如果我把鼠标悬停在某个点上,就会显示那只狗狗的照片。这是猴面犬。这是一个很有趣的例子,它能更生动地展现我们从数据中看到的内容。我是如何收集这些数据的呢?正如我提到的,美国养犬俱乐部(American Kennel Club)有一个公开的数据集,我把这些照片保存在一个文件夹里,然后把它们合并在一起。
我们将一起来看看,首先让我带您概览一下,让您预览一下第一个示例中的内容。我将首先介绍如何导入多个文件,以便轻松地从文件夹中导入图片。然后,您将看到工作流构建器如何将这些图片与 AKC 数据集合并,并生成一张图像。我们将看到这个示例从简单到复杂的演变过程。
在最后一个迭代中,您将看到如何使用一些自定义 JSL 代码在工作流构建器中创建用户提示。我们首先来看看如何使用导入多个文件来导入图片。我这里有一个名为 AKC 的文件夹,里面包含狗狗的图片。它还包含其他文件,但大部分是狗狗的图片,您可以看到这些狗狗图片都以犬种名称命名。这一点很重要,因为我们将使用这些信息与 AKC 数据集进行关联,该数据集也包含犬种名称。在开始之前,我将创建一个新的工作流并点击录制。
现在我们来导入多个文件,并导航到这些文件所在的文件夹。这里是AKC文件夹,我们要选择仅包含图片的文件。然后我们添加一个文件名列,因为我们希望将犬种名称添加到数据表中。现在可以看到,一步就导入了28张图片。接下来,我可以编辑文件名列。我需要去掉.JPG后缀,以便将其与AKC文件夹中的犬种名称关联起来。
我将停止工作流。我想展示的是,JMP 正在以 JSL 格式记录我工作流中的这些步骤。我们打开已完成的工作流。您可以在这里看到已完成的工作流,我将为您演示一下。这是我之前录制的,其中导入了数据并创建了这些步骤。但我想特别说明一点:当您导入多个文件时,JMP 会将导入的数据表命名为第一个文件名,并在最后一个文件名后加上下划线。
我的AKC文件夹里,我的第一只狗登记的是猴面犬,最后一只狗登记的是水獭猎犬。我来演示一下这个工作流程,这是结果。图表和你之前看到的一样,只是我把点替换成了狗狗的照片。
现在,我们来看看这些行为类别。我将行为分为四类,分别是警觉、反应灵敏、主动和外向。在完整的AKC数据集中,共有277行数据。由于我只使用了28张图片,所以实际的类别比图表中显示的要多。我特意省略了冷漠和警惕的犬只,这样可以向您展示这个工作流程的可复用性。
我们将向AKC文件夹中添加四只性格孤僻的犬只,然后重新运行此工作流程,以便您了解其适应性。再次强调,此工作流程最初是针对28只犬只构建的。我打开这个文件夹。最后一只犬是那只水獭猎犬。我们将从右侧导入这四只性格孤僻的犬只,并将它们放入AKC文件夹,而不是AKC2文件夹。
这是我们的AKC文件夹。我把新添加的狗狗数据粘贴进去。现在我们已经把这些冷漠的狗狗添加到AKC文件夹里了,接下来我们重放一下工作流程。现在你可以看到,图表里已经添加了这些冷漠的狗狗。这就是工作流程构建器的灵活性。我们录制了一个工作流程,它可以导入图片,将其与AKC数据集连接起来,进行一些数据清理,并生成图表。然后,当我们向该文件夹添加更多文件时,只需点击运行,所有内容都会自动更新。
让我们深入探讨一下工作流程中的一个步骤。接下来会稍微复杂一些,需要稍微破解一下代码,但不会太复杂。我们可以看一下导入多个文件的步骤,并查看捕获到的 JSL 代码。JMP 正在访问一个特定的文件夹路径,我的狗狗照片就存放在那里。
如果我想引用另一个文件夹,只需修改这个文件路径即可。我正好还有一个名为 AKC2 的文件夹,里面有更多狗狗的照片。我在这里做的只是做这个小小的改动,然后我们就可以重新运行流程了。这次,你会看到 53 只狗狗而不是 32 只,生成的图表也会更加丰富。
跟踪代码的一种简单方法是查看步骤设置并对 JSL 代码进行一些小的调整。现在,在最后一次迭代中,我们将再做一项更改。如果我想把这个工作流程分享给其他人运行,那么修改第一步,让用户从自己的目录中设置文件文件夹就很有意义了。
我们稍后会再次回到这一步,然后向下滚动到最底部。我们可以用“创建窗口”替换“导入数据”步骤。我建议在这里做的另一个改动是,将文件夹路径替换成更通用的路径,比如“桌面”,或者像我这里写的“文档”。现在我们来执行第一步。
现在您可以看到文件夹已默认设置为“文档”。我的所有选择都已保留,例如“添加文件名”列,并且系统会提示用户导航到图片所在的位置。为了总结这个示例,我们了解了如何使用“导入多个文件”将图像导入到单个表中,然后我们了解了如何使用工作流构建器创建可适应的工作流。接下来,我将把第二个示例交给 Monique。
当然。谢谢你,温迪。让我共享一下屏幕。好了。我要隐藏会议控件。好了。很好。我们都同意,它们比眼镜的照片可爱多了。这真是一个很棒的例子。第二个例子,我们要看一下PDF中的数据。
为什么呢?我以前做研究的时候,有时会深入研究某个课题,然后在一些PDF文件里发现非常有用的信息。这些信息可能是化学参考表格、成分数据,也可能是供应商提供的表面活性剂信息、原材料信息,或者分析报告。
通常情况下,数据量很大,我不想手动将这些数据复制到数据表中。那么,我们该如何将这些数据导入JMP呢?今天我将首先演示的是,我们将从点击式PDF导入向导开始,它与Excel导入向导和其他导入向导非常相似。
这是一个很好的起点。我们将结合工作流构建器使用它,然后像温迪那样,对源代码进行一些修改,以帮助我们实现导入自动化,并简化流程中的某些部分。
在 JMP 18 中,工作流构建器新增了一个很棒的功能,可以有效解决清理工作中的一个问题。导入大量 PDF 页面后,我们需要清理这些页面,其中可能包含很多表格。现在,工作流构建器允许我们查看这些表格。我稍后会演示这个功能。好了,就到这里。首先,我来介绍一下我们要处理的 PDF 文件。我打开它。就是这个。
我们将来看一个例子,这是一个两页的PDF文件,其中列出了常见脂肪的脂肪酸组成。第一页列出了动物源性脂肪的组成,第二页列出了植物源性脂肪和油脂的组成。
它看起来只是一个格式非常整齐的表格,但当我们仔细查看第一页时,会发现虽然对于 PDF 来说看起来不错,但对于 JMP 数据表来说却存在一些问题。这表明,导入数据后,我们需要做很多工作才能将其转换为可用的格式。
例如,我们实际上没有列标题。第一列是类别。然后是百分比列。这里还有一列百分比列。这里有两列列出了脂肪酸。一列列出饱和脂肪酸,另一列列出不饱和脂肪酸。
这里还有另一列。另一个问题是这里有子标题。例如,“牛油”就是一个子标题,它有小计。我们可能需要删除小计,但显然,我们还需要将这个子标题的内容填充到空白处。
这是另一个问题。正如我所说,有些子标题跨越了两行,这显然也会在 JMP 中造成问题,因为 JMP 无法识别它们应该放在一起。
此外,我们还会遇到像这样跨越多列的数据。导入这些数据后,我们需要清理很多问题。让我们回到日志,先看一下最终结果。我们真正想要的是使用 JMP 导入这两个页面,最好只处理其中一个页面,然后再进行所有清理步骤。
再次提醒,我们最好只在一个页面上操作,然后让 JMP 应用于两个页面,再将数据合并起来以便使用。我已经把这个过程录制到工作流中了。这是最终结果,之后我们会重新创建它。让我先演示一下这个工作流。
这里打开了两个页面,工作流构建器正在执行一系列清理步骤。这些步骤很多。它首先处理第一个数据表,然后重置并处理第二个数据表。完成后,它会将这两个数据表合并,并根据合并后的数据输出结果。
好了。这次我们比较的是饱和脂肪和纯饱和脂肪。好的,我来关闭这些输出,方法是回滚或重置我的工作流程。实际上,我要完全关闭这个工作流程,然后打开一个空的工作流程。我会把它停靠在我今天正在处理的项目的右侧。
好的,我们从头开始,打开PDF文件。我本来想展示一个PDF导入完美运行的例子,但我想还是算了,你们只需要相信我,有时候你用JMP打开一个PDF文件,JMP就能完美识别你想要的数据表,只需点击两下鼠标,就能把它导入到数据表中。这就是一个完美的例子。
我举个不太完美的例子。让我打开这个PDF文件。我可以双击这里的链接,打开PDF导入向导。你可以立刻在左侧的预览中看到,JMP无法像以前那样识别这个表格。我们能识别出其中的一部分,但这部分内容无法使用。
首先,我们需要选中“忽略所有表格”,这样就能重置所有设置。重置完成后,我就可以用鼠标选中这个表格了。
这样做的时候,JMP 会猜测列的位置。我这里稍微放大一下。这样你就能看到它并没有识别出所有的列。这是因为有些标题跨越了多列。
这没问题,因为我可以右键手动添加。例如,我可以来到体重百分比的右侧,右键点击,然后添加列分隔符。接下来,我需要在第二个体重百分比列的位置做同样的操作,在这里添加列分隔符,在那里也添加列分隔符。
就这张表格而言,目前已经是最佳状态了。需要注意的是,红色三角形下方还有一些选项。例如,您可以设置用作表头的行数,这也是一个非常有用的工具。
在这种情况下,我只导入第一个表格。当然,我也可以在第二页做同样的选择,这不会太麻烦,因为这只是一个两页的PDF文件。但如果表格有10页或20页呢?那就需要点击很多次,添加各种列分隔符,可能会比较繁琐。
我先导入第一页,看看接下来能做什么。我点击确定。我忘了启动工作流程录制器,所以约翰提醒我。我说,好的,请录制。这里表格已经导入,这一步也已经录制好了。我停止录制。我双击录制步骤,把它稍微移开一点,这样我们就可以查看JSL(工作流日志)了。
这是导入第一步的代码。我们可以看到它是如何运行的。这是文件所在的位置。然后是一个 PDF 表格函数,接着是另一个表格函数,然后是一个名为“表名”的参数。实际上,这就是我的数据表的名称。我看到了一些关于行、异质性的内容,然后是第 1 页。接着我看到一个矩形。那应该是我之前绘制的矩形,我还看到了列边框。这些应该是我想放置所有分隔线的坐标。
看到这个,我就很想试试看能不能添加第二个页面。我们来试试吧。我们想添加第二个页面。就把这个页面放到“2”的位置。表格名称也一样,我们要把“1”改成“2”。
现在我想运行这段代码,我可以右键点击并选择“运行脚本”直接运行。我们来试试。现在第二个表格打开了。我把它缩小一点,再看一下打开的第二个表格。
我立刻就能看出成功了,因为在这个数据表中,我包含了植物油和脂肪。这是我的第一个页面表格,里面是动物脂肪。我只需修改工作流构建器为我捕获的脚本,就能轻松导入第二个页面。复制粘贴,或者我再说一遍,复制粘贴或修改这里的代码可能比我手动点击并添加所有列分隔符要快得多。这或许能节省一些时间。
接下来我想做的是为第二部分——清理工作——做准备。我先演示一下,然后再解释我为什么要这么做。我希望通过一个步骤就能打开这两个数据表。我需要知道的是,当我使用 PDF 导入向导导入两个表格时,JMP 会如何记录这个过程。如果我不知道,最简单的办法就是重新开始记录。首先,我要重置这里的输出,关闭这个窗口,只是为了保留这个窗口。
现在我重新开始录制,然后点击一个PDF文件。接下来我要忽略所有表格。我不太关心这些表格的具体样式,我只想看看如果每页放两个表格会发生什么。点击“确定”。我要查看一下相关的步骤代码。
这是该步骤的代码。对于第一个步骤,我认为它从这里进入了这一步。当我导入两个表时,JMP 似乎重复使用了表函数。这里我有一个表,然后是一个逗号,接着是另一个表。这似乎是导入两个表的结构。
既然我知道了,我可以删除这一步。我不需要它。我可以稍后再回到这一步。现在我想做的是,我把这个框再放大一点,然后把光标放在第一个表格的括号左边,这样就能选中右括号。找到了。现在我知道需要复制所有这些内容,我只需按 Ctrl + C 即可。然后,把前面的内容向下移动,按 Ctrl + Pace 粘贴进去,再添加逗号,就像我们刚才发现的那样。
现在我可以先改一下,我要把它改回1。我要把标题改回1,页码也改回1,然后第二个页面会显示第2页,第2页。好了,我们把这些都关掉,看看这样行不行。
当我执行这一步时,确实得到了这两个数据表。这就是我现在一步完成所有操作的原因。我为什么要这样做呢?我这就解释。我要关闭输出。我要关闭这个工作流,然后打开另一个工作流。我还要把它再次停靠到右侧。
这个工作流程包含这一步。我双击这里导入两个表格。这是我的表格 1,这是我的表格 2(位于第 2 页)。然后我录制了一些清理步骤,这些步骤都针对表格 1 进行。当我选中第一个步骤时,可以看到它位于第 1 页。我把所有清理步骤都分组了,可以看到有很多。本次演示中我们不会详细介绍,但之后会提供相关资源供您查阅。
现在重要的是,我们已经对其中一个数据表完成了所有清理步骤,那么如何对第二个数据表执行相同的操作呢?在 JMP 18 中,这变得非常简单。我们只需要右键单击并选择“分组宽度”即可。让我先说明一下。我已经选中了所有需要重复执行的清理步骤,然后我将右键单击并选择“分组宽度”。
现在 JMP 已经为每个项目对这些步骤进行了分组或分类。但是它提示没有选择任何源。我得处理一下。我需要告诉 JMP 循环执行哪些步骤。为此,我需要在“步骤设置”下查看源。这很简单。我只需要告诉 JMP 指向生成多个输出的工作流步骤即可。
在这种情况下,我将选择“导入到 PDF 页面”步骤。在这个步骤中,我创建了两个表格。现在 JMP 就知道需要对生成的两个输出执行所有这些步骤。我们来看看是否有效。
我要运行一下。我们打开了两个输出。它在运行。不,它还没运行。它正在执行第一个表格的步骤。然后,当它完成某个步骤后,它应该会切换到第二个表格。好了,它开始运行第二个表格了。我觉得这真是个很棒的功能,尤其是在有两个以上表格的情况下。
我最近导入了一个13页的PDF文件。导入之后,我清理了其中一个表格,然后查看了所有13页文件的操作步骤。效果非常好。好了,这就是我想展示的内容。
接下来我们来看最后一个例子。这个例子是关于从网站导入数据的。这完全是我在研发部门工作时做的。当时我需要获取水硬度的数据。水硬度是配方设计中的一个重要考虑因素。我在一个网站上找到了一些非常有用的信息,并非常仔细地整理出了配方。接下来,Wendy会给我们讲解如何更优雅地完成这项工作。我就不再赘述了,接下来交给Wendy吧。
好的,听起来不错。好的,我们来看例3,我们会仔细研究一下“For Each”循环,或者简单来说,“For Each”就是循环。我们来看看Monique找到水硬度数据的网站。我现在在HydroFlow USA网站,如果我们进入这个交互式地图区域,我可以导航到美国地图。
HydroFlow USA 提供城市级别的水硬度数据。我将导航到我们都居住的明尼苏达州,然后点击此链接向您展示包含明尼苏达州信息的页面。该页面包含一个表格,列出了各个城市、对应的邮政编码以及两种不同单位的水硬度。
查看这个网址,其他州的网址结构也相同,都是州名加上水硬度。莫妮克的问题在于如何从网上获取这些数据,以便完善她的分析。
使用 JMP,我将所有州的饮用水硬度数据导入到这样一个数据表中。可以看到,表中有 855 行,因为每个州包含多行数据,分别对应多个城市。有了这些数据,Monique 就能扩展她的分析。如果我播放这段视频,你会看到,它能非常简洁地模拟出各州的饮用水硬度。
在示例 3 中,我将向您展示一些工具。其中一个工具是使用 JMP 的 Internet Open 函数从网页访问数据。然后,我们将对这个 Internet Open 函数进行循环处理。我们将它封装在一个循环中,以便将所有州的数据汇总到一个表格中。
我们先来看看“Internet Open”功能。我先来获取一下网页的URL。我直接用Ctrl+C复制这个包含“明尼苏达州水硬度”的网页,然后创建一个工作流。点击录制,现在我们依次点击“文件”、“Internet Open网页”。粘贴URL,然后点击确定。
JMP检测到该页面上有一个表格。我点击“确定”继续。这应该能让你初步了解从单个页面导入数据的功能。
我进入工作流程并停止录制。查看录制内容,发现 JMP 正在运行或录制这段 JSL 代码。它其实就是一个包含 URL 名称的 open 语句,以及一些关于它是一个 HTML 表格的详细信息。考虑到这一点,我们不希望每次都要单独访问这 51 个页面。
理想情况下,我们应该有一个导入步骤,可以循环遍历所有州。现在我们再来讨论水硬度,但首先我们要看一下 JMP 文档中的一个示例,该示例描述了 for each 语句的工作原理。
如果你点击资料中的这个链接,就能直接跳转到示例。我会在幻灯片中讲解这个示例,然后我们一起动手搭建。哦,好的。让我打开幻灯片。
我会确保在上传的版本中修复这个问题。好的,JMP 文档示例中的目标是创建一组图表,具体来说,就是为每种性别分别创建三个分布图。示例中使用的数据集是糖尿病数据集,其中包含两种性别。构建方法是从糖尿病数据集中创建一个包含性别 1 和性别 2 的子集,然后仅针对性别 1 创建分布图,最后将步骤 2 封装在一个 for each 循环中,这样工作流程就可以同时适用于性别 1 和性别 2,而无需实际记录性别 2 的步骤。
让我们从头开始构建这个流程。我将创建一个新的工作流,然后点击“录制”。我们来找到糖尿病数据集。这就是糖尿病数据集,这里可以看到性别 1 和性别 2。我们首先按性别进行子集化。我们再来一次,因为我们想要取消选择某些行。按性别进行子集化。在预览中,您可以看到性别 1 和性别 2。我应该得到两个表,没错。这是性别 1 和性别 2 的表。
我先从性别1开始,创建可视化图表。为了简单起见,我将创建一个包含三个变量的分布图。现在我进入我的工作流程。我们进入正确的工作流程。在这里你可以看到,我实际上录制了好几个步骤,因为我需要重复几次。
接下来你会看到一些制作过程。因为我已经重新提交了,所以我们会删除不需要的步骤。我们先运行一下,确保我们需要的内容都已准备就绪。打开数据表,将数据表子集化为性别 1 和性别 2,然后我应该就能得到性别 1 的分布情况了。好了。性别 1、性别 2,然后这里就是性别 1 的数据。
现在,对于每个循环,我将选择这个报告步骤,右键单击并选择“分组”>“循环”。这就是我想要循环执行的内容。现在,如果我运行到这个循环,已经选中的工作流步骤是我之前进行子集划分的步骤,所以这里不需要做任何更改。现在,当我重新运行工作流时,你会看到运行了两个分布,分别对应两种性别。好了。这是性别 1,这是性别 2。
我们如何使用这种框架从 HydroFlow 获取所需的水硬度数据?这里需要做一些清理工作。我们将回到幻灯片,并针对水硬度进行调整。考虑到我需要遍历各个州,我的想法是,创建一个类似于糖尿病示例的表格,然后将该表格细分为包含 URL 的每个州的单独表格。我将记录其中一个州的网络开放情况,然后将该网络开放情况封装在一个 for each 循环中,以便它能够记录所有州的网络开放情况。
我们来演示一下我完成的工作流程。你会注意到,演示过程中只会用到少数几个状态,因为如果包含所有状态,演示时间会太长。我只会运行数据清理步骤之前的部分,这样我们就可以先讨论一下,然后再演示剩余部分。
“州”表被打开,然后被细分为包含 URL 的各个州。现在您可以看到每个州的互联网访问过程。如果您查看工作区,我已经完成了这五个州的互联网访问。
如果我回到工作流程并启用其余步骤,您将看到所有这些数据合并到一个状态表中,同样,在这种情况下只有五个状态,然后是一个显示水硬度的图表。
我们来看一下工作流程,以下是每个步骤的说明。接下来,我要介绍一下这个示例中存在的额外复杂性。在“导入 HTML”步骤中,为了打开 Internet,需要添加一些自定义 JSL 代码。展开来看,我修改了从工作流程构建器录制的这个导入步骤。现在,我将回到幻灯片中,以便我们讨论这些具体的更改。
这段语句是工作流构建器在我打开阿拉巴马州网页时记录的内容。由于我需要引用所有州的数据,我将用一个通用变量来替换它,这个变量就叫做“网址”。然后,如果我们只考虑阿拉巴马州的数据表,我需要能够通过这个网址引用数据表中的特定单元格,而该单元格包含的是URL。
通过学习 JMP 脚本语言,可以与数据表进行交互,只需说“数据表”,然后就能得到数据表的名称。
当我们引用数据表中的某一列时,需要先写出数据表名称,然后加一个冒号,最后写上列名。例如,数据表名为 `state`,列名为 `Alabama`,URL` 就是列名。最后,因为我们需要指定包含 URL 的单元格,所以要加上括号。对于所有州,列名都是数字 1,因为每个表都只有一行,而这一行就是包含 URL 的单元格。
总结一下这个例子,你看到了如何使用 Internet Open 来从网页获取数据。然后我们深入探讨了 JMP 文档示例中的 for each 循环。接下来,你看到了我是如何通过一些自定义 JSL 代码来修改它,从而访问 Internet Open 中的数据的。最后,我会把总结部分交给 Monique。
是的,谢谢 Wendy。今天我们向您展示了如何导入各种数据,包括图像、PDF 数据、网页数据,以及如何在不编写脚本的情况下实现自动化。Workflow Builder 是一款非常棒的工具。您还可以通过查看它为您记录的 JSL 代码并进行一些小的修改来进一步扩展其功能。不要害怕查看 JSL 代码,大胆尝试吧!感谢您今天的参与,希望这对您有所帮助。