在现有列上使用逻辑测试在 OpenRefine 中创建列?

Create column in OpenRefine using a logic test on an existing column?

我有一个原始数据集,其中包含 4,500 多个代表土地交易的行条目。现有列之一是 "Place,",在每个单元格值中,我通常将地点名称设为 Some Neighborhood,但有时当有地方我不知道时,我会添加其他信息来自公证记录,例如 Some Neighborhood, Some County 甚至 Some Neighborhood, Some County (nicknamed).

我想使用这一栏中的信息创建两个新栏。第一列包含上级行政区划,第二列包含上级行政区划 -- 有点像缩小。

我认为我需要使用一种逻辑测试或 if-if-if- 测试基于现有列创建一个新列,在其中我可以枚举属于 [=] 的 Some Neighborhood 的值16=] 或 County 2City 1 等。然后,基于这个新列,我将创建另一个可能具有 State 1State 2 等的列使用相同类型的测试。

如何在 Open Refine GREL 中使用正则表达式编写此代码?如何将单元格中找到的多个 可能 值串在一起?我尝试使用 cellsvalue.contains,但我不知道如何像这样将倍数串在一起。

所以再次回顾一下,我想编写一种方法来创建一个新列,该列包含基于现有值列的新单元格值,例如

"if Street1,Street2,Street5, 但不是 Street3,或Street4然后 County1"

"if Street1 or Street2 or Street5, then County1 AND Then IF Street3 or Street4 then County2"


编辑: 这是一些数据:

land sale   0.350   carreau 350 gourdes Bullet
land sale   1.000   carreau 700 gourdes Campèche
land sale   0.200   carreau 220 gourdes Bremont
land sale   0.500   carreau 150 gourdes Pierrette
land sale   5.000   carreau 225 gourdes Lagenivrée
land sale   0.125   carreau 200 gourdes Bullet
land sale   1.000   carreau 300 gourdes Tozin
land sale   0.125   carreau 100 gourdes Dufort
land sale   0.250   carreau 135 gourdes Charitte, Savann Brute
land sale   0.500   carreau 300 gourdes Ravines des Roches
land sale   0.500   carreau 80  gourdes Isidore (Nègre Libre)
land sale   0.500   carreau 215 gourdes Nordette (Boures)
land sale   0.250   carreau 200 gourdes Bullet (Morne Montègue)

这是一个包含两个新列的预期结果示例,假设 "Commune" 和 "Section":

land sale   0.350   carreau 350 gourdes Limonade    Bwadlans    Bullet
land sale   1.000   carreau 700 gourdes Limonade    Bwadlans    Campèche
land sale   0.200   carreau 220 gourdes Limonade    Bwadlans    Bremont
land sale   0.500   carreau 150 gourdes Limonade    Roucou      Pierrette
land sale   5.000   carreau 225 gourdes Limonade    Roucou      Lagenivrée
land sale   0.125   carreau 200 gourdes Limonade    Bwadlans    Bullet
land sale   1.000   carreau 300 gourdes Quart_Mor   Sablé       Tozin
land sale   0.125   carreau 100 gourdes Limonade    Bwadlans    Dufort
land sale   0.250   carreau 135 gourdes Limonade    Bwadlans    Charitte, Savann Brute
land sale   0.500   carreau 300 gourdes Limonade    Bwadlans    Ravines des Roches
land sale   0.500   carreau 80  gourdes Limonade    Bwadlans    Isidore (Nègre Libre)
land sale   0.500   carreau 215 gourdes Limonade    Bwadlans    Nordette (Boures)
land sale   0.250   carreau 200 gourdes Limonade    Bwadlans    Bullet (Morne Montègue)

有多种方法,您选择哪一种可能取决于您在初始位置列中有多少个值。

我推荐第一种方法作为起点

方法 1 - 使用构面:

  • a) 添加空白列(例如 Commune、Section)(通过使用 'add 基于此列的列'来自任何现有列,并使用 'null' 作为 GREL 公式)
  • b) Facet on Place 列,select 一组 同一社区和部门中的价值观(例如 'Bullet','Campéche','Bremont', 等)然后写公式更新 带有 'Bwadlans' 和 'Limonade'
  • 的公社和部门专栏
  • c) 重复 每个 commune/section 有一组 Places

方法 2 - 使用查找: 如果你已经有了 Places -> Commune & Sections 的映射,你可以将其创建为一个单独的 OpenRefine 项目,然后使用 'cross' 为每个 Place

查找 Commune/Section
  • a) 创建包含 Place、Commune 和 Section 列的 OpenRefine 项目(每个地方一行)
  • b) 在初始项目中,使用 GREL 创建一个基于 Place 列的新列,例如:cell.cross('place mapping project','Place')[0].cells["Commune"].value
  • c) 重复 (b) 但对于 Section 值,例如cell.cross('place mapping project','Place')[0].cells["Section"].value

方法 3 - 使用条件: 这是我认为您首先要求的方法,但我认为这不一定是最佳选择

  • a) 使用来自任何 Place 列的 'add column based on this column',像 if(or(value=="Bullet",value=="Campéche"),"Bwadlans","")
  • 一样使用 GREL
  • b) 对于其他位置,您可以通过参考 Place 列中的值在新列上编写类似的 GREL - 例如if(or(cells["Place"].value=="Pierrette",cells["Place"].value=="Lagenivrée"),"Roucou")

请注意,要使用两个以上的条件,您必须嵌套 'or' 语句,例如: or(or(value=="Bullet",value=="Campéche"),value=="Bremont")

通过安装有助于此过程的 OpenRefine 扩展,可以使方法 2 和方法 3 变得更容易(建议方法 2 使用 VIB-BITS 扩展,方法 3 使用 'inArray' 函数查看 gokbutils 扩展- 这将避免复杂的 'or' 语句)

正如您在 Owen 的回答(方法 3)中看到的那样,GREL 的条件很难处理。如果这确实是您想要执行的操作,请改用 Python/Jython。这是一个基于您的数据的示例:

value = value.strip().lower()

if "pierrette" in value or "lagenivrée" in value:
    return "Limonade||Roucou"
elif "tozin" in value:
    return "Quart_Mor||Sablé"
else:
    return "Limonade||Bwadlans"

然后使用 || 拆分新列作为分隔符(参见截屏视频)。

您当然可以使用方括号和 not in.

创建更复杂的条件

假例子:

    value = value.strip().lower()

    if "pierrette" in value or "lagenivrée" in value:
        return "Limonade||Roucou"
    elif "tozin" in value:
        return "Quart_Mor||Sablé"
    elif ( ("ravinne" in value or "lagenivrée" in value) 
           and ("des roches" not in value or "savan" not in value)):
        return "Somewhat||Somewath else"
    else:
        return "Limonade||Bwadlans"