《Using OpenRefine》翻译~19(完结)

上一篇:《Using OpenRefine》翻译~18


GREL 

正则表达式的强大功能并不限于数据查找,还可以用作数据管理。GREL提供了利用正则表达式完成函数操作的可能。GREL是用来操作数据的简单函数语言。其是OpenRefne内置的,并且包含函数参数设置。前几章我们已经简要的接触过了,这里我们将教你如何构建你自己的GREL表达式。  

 

 

数据转换

在你需要对数据进行转换的时候就需要用到GREL。你可以直接对数据进行修改(通过点击相应列菜单:Edit cells | Transform… )或者创建基于某列的新列数据(通过点击相应列菜单:Edit column | Add column based on this column… )。我们将对Object Title 列进行操作演示。

当你打开转换对话框后,你会发现默认有一个GREL表达式叫做value,其作用就是返回源值。这当然并没有多大用处,但是我们可以以此为基础进行扩展。举个例子,GREL表达式"TITLE: " + value + "." 在源值的前面增加了文本TITLE:,在最后增加了一个点。但是注意这里的文本必须括在双引号或者单引号内,不然的话OpenRefne会理解错误。在你输入完成后你就会发现预览窗口显示了数据更新。

更有用的功能是改变文本。举个例子,我们可以用value.replace("stone", "stones") 将字符串stone替换为 stones。这里我们通过在value后加小点来调用replace函数。我们这样就是告诉了OpenRefne将所有值的stone的替换为stones。

对于上面,如果我们组合上正则表达式,那么将更加强大。你可以看到,有一些单元格值是以数字开头的。我们可以用value.replace(/^\d+ /, "")将这些数字删除。这里正则表达式被正斜杠“/”包含,要替换成的值用双引号包含。

我们还可以使用组符来增强功能。其不光可以将多个字符标识为一个单元,还可以后续使用这个单元以做更多用处。这样的话,我们就可以将开头的数字替换成更加容易理解的内容。举个例子:我们需要将234 替换成 Object 234: ,我们就可以使用如下表达式:value.replace(/^(\d+) /, "Object $1: ") 。你是用美元符号跟一个数字来定义组,第一组叫做$1,另外$0代表整个表达式的结果。

表达式可以完成任意功能,只不过取决于表达式的复杂程度。比较难的例子是我们曾经对Categories 列中的多值内容分析时,有些包含空值。举个例子,"|Stones||Bones|||Buildings" 实际上只包含三个值,但是如果你针对管道符进行拆分时,你会得到七个值(包括四个空值),这是因为这里有六个管道符。我们可以剔除这些多余管道符。值开始的管道符必须删除,所以我们可以先用value.replace(/^\|/, "")。这看上去有些复杂,因为这里的管道符必须使用反斜杠,以防止被认为是正则表达式中的特殊字符。将连续出现的多个管道符改为一个,我们可以使用value.replace(/\|+/, "|") 。记得在正则表达式中管道符需要使用反斜杠,而替换字符串位置不需要,因为替换字符串位置不可能存在特殊的意义。

OpenRefne除了replace函数外还有大量其他函数,你可以在表达式编辑窗口中点击Help 页查看,或者也可以访问https://github.com/OpenRefine/

OpenRefine/wiki/GREL-Functions。比如split函数,我们对Categories 列使用value.split("|").length() ,可以计算每个单元格中有多少不同的值。这里,我们首先让OpenRefne按照管道符“|”进行分割,然后使用length函数计算分割后的值数量。你甚至可以创建更加复杂的表达式:value.split("|").uniques().join("|")。这个表达式可以一次解决我们在第三章:高级数据操作 介绍过的移除重复值的所有操作。 

    

 

 

创建自定义透视功能

现在该到介绍一些曾经略过未说的内容了:每次你创建一个透视,你实际上是执行了一个GREL表达式。比如,让我们点击Object Title 列下拉菜单:Facet | Customized Facets | Facet by blank. 。然后在出现的透视窗口右侧顶部中点击change 链接, OpenRefne就会显示隐藏的表达式窗口,这里你就可以自定义透视表达式,如下图所示:


我们看到空值透视的表达式是isBlank(value) 。实际上,如果值为空值的话,isBlank函数会返回true,如果非空,则返回false。我们可以做下修改。比如,我们想知道是否标题是以数字1开头的,那么这个表达式子就可以是value.startsWith("1") ,这样我们就能够得到一个透视,如果内容以1开头则返回true,反之返回false(出现(error)表示是值为空)

这是一个学习GREL的好机会。因为每一个透视其实都创建了一个GREL表达式,你可以学习其底层的工作方式。比如Duplicates 透视就会教你学习facetCount 函数。如果你有疑问,记得所有的表达式都可以重新编辑,你也可以通过Help页学习具体函数的用法。

如果你想创建自己的透视,完全不需要从已存在的透视再修改的方式进行。比如,如果你想对categories 列中分类数量进行透视,你可以点击Categories 列下拉菜单:Facet, Custom text facet…. 输入表达式value.split("|").length() 然后点击 OK.你会发现左侧出现了一个 Categories 透视窗口,你可以在此选择分类数量。这里你发现表达式输出的都是数字,所以你可能想做一次数字透视来替代,那么只需要选择菜单:Facet | Custom numeric facet… 这样你就可以按照数字方式进行透视了。自定义透视是探索数据细节的好方法,并且不怕数据会被误操作。

 

GREL排障

最后,如果你的表达式未能够满足你的要求该怎么办呢?比如,我们在第2章:分析和修改数据中,对Registration Number列应用重复透视的时候效果良好,但是对Record ID列就不怎么样,让我们修复这个问题。点击Record ID 列下拉菜单:Facets | Customized facets | Duplicates 。 

请确保数据为未经过清理的源数据,否则重复项如果已经去除就无法继续操作了。

就像你预料的那样,OpenRefne 没有检测出重复项。所以让我们修改表达式,点击Change 链接,我们发现表达式如下:

facetCount(value, 'value', 'Record ID') > 1

产生这个问题的原因是value值这里是数字,而facetCount 函数只对字符串有效。解决的办法是将value 转换成字符串,如下:

facetCount(value.toString(), 'value', 'Record ID') > 1 

这样就能够检测出重复项了。

你可能会有疑问:我怎么样才能找到这种解决办法呢?方法就是不断的练习和尝试。你使用OpenRefne 分析、清洗、链接了越多的数据集,你就会越加有处理感觉。另外,你也会获得越多的正则表达式和GREL知识,进而成长为一个专家。从此以后,你就可以一步步处理更复杂的数据集。本书就为你指明了方向,现在就看你的了。



【完结】

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值