Metabase学习教程:提问-7

清理和格式化文本

 

如何使用自定义的文本,清理非结构化或不一致的文本。

 

假设Metabase想为我们可爱的社区举办一个晚宴。对于主菜,我们有牛肉炖牛肉或鹰嘴豆炖菜,而对于两侧,我们有印度菜或烤蔬菜。我们已经发送了一份关于菜单选项的调查,这样每个人都可以告诉我们他们想吃什么。

 

不幸的是,我们忘记在表单上设置数据验证,因此响应如下所示:

 

Response ID | Main | Side |

 

|-------------|-------------------------------------|-------------------------|

 

| 1 | beef tibs | injera |

 

| 2 | chickpea stew | grilledvegetables |

 

| 3 | BEEF TIBS WITHCHICKPEA STEW PLEASE | |

 

| 4 | | GrilledVegetables |

 

| 5 | Surprise me. | |

 

我们希望:

 

[if !supportLists]1. [endif]整理并结合主食和副食,这样我们就可以数出最受欢迎的饭菜了。

 

[if !supportLists]2. [endif]处理在某些方面无效的响应(例如多个电源,或者菜单上不存在的电源)。

 

[if !supportLists]3. [endif]跟踪提交了缺少信息的回复的客人。

 

总的来说,我们希望最终得到一个如下所示的表(向右滚动可查看完整的表):

 

Response ID | Main | Side | Order | Follow up? |

 

|-------------|-------------------------------------|-------------------------|---------------------------------------|------------|

 

| 1 | beef tibs | injera | beef tibs with injera | no |

 

| 2 | chickpea stew | grilledvegetables | chickpea stew withgrilled vegetables | no |

 

| 3 | BEEF TIBS WITHCHICKPEA STEW PLEASE | | beef tibs only | yes |

 

| 4 | | GrilledVegetables | grilled vegetablesonly | yes |

 

| 5 | Surprise me. | | |yes |

 

[if !supportLineBreakNewLine]

 

[endif]

 

搜索和提取文本

 

我们假设唯一有效的主要选择是牛肉和鹰嘴豆炖菜。我们可以使用regexextract函数检查每个响应中的有效菜单选项。

 

在中搜索值主“牛肉tibs”专栏,我们将创建一个自定义列使用regex模式(?i)(beef

 

tibs)。此regex模式执行不区分大小写的检查,以查看“beef tibs”是否出现在响应中的任何位置。

 

创建牛肉自定义列使用:

 

regexextract([Main],

 

"(?i)(beef tibs)")

 

您应该得到输出:

 

| Response ID | Main | Beef |

 

|-------------|-------------------------------------|-----------|

 

| 1 | beef tibs | beef tibs |

 

| 2 | chickpea stew | |

 

| 3 | BEEF TIBS WITH CHICKPEA STEW PLEASE |BEEF TIBS |

 

| 4 | | |

 

| 5 | Surprise me. | |

 

然后,我们要搜索主有效值“鹰嘴豆炖菜”列。

 

创建鹰嘴豆列:

 

regexextract([Main],

 

"(?i)(chickpea stew)")

 

通过输出:

 

| Response ID | Main | Chickpea |

 

|-------------|-------------------------------------|---------------|

 

| 1 | beef tibs | |

 

| 2 | chickpea stew | chickpea stew |

 

| 3 | BEEF TIBS WITHCHICKPEA STEW PLEASE | CHICKPEA STEW |

 

| 4 | | |

 

| 5 | Surprise me. | |

 

 

 

合并来自不同列的值

 

接下来,我们将创建一个名为主(干净)这将合并每个客人的响应的有效干线。我们想建立一些逻辑如果主包含:

 

一个有效的选择(牛肉或鹰嘴豆炖),然后填充主(干净)有这个选择。

 

多个有效选项,然后将第一个(最左边)有效选项放入主(干净).

 

没有有效选项,然后填充主(干净)具有空值(空字符串)。

 

创造主(干净),我们将使用凝聚功能来处理上面列出的三个案例,然后把整个事情包装成降低功能以小写标准化所有内容。

 

lower(coalesce([Beef],[Chickpea],""))

 

这将给出输出(向右滚动可查看完整的表):

 

| Response ID | Main | Beef | Chickpea | Main (Clean) |

 

|-------------|-------------------------------------|-----------|---------------|----------------|

 

| 1 | beef tibs | beef tibs | | beef tibs |

 

| 2 | chickpea stew | | chickpea stew | chickpea stew |

 

| 3 | BEEF TIBS WITHCHICKPEA STEW PLEASE | BEEF TIBS | CHICKPEA STEW | beef tibs |

 

| 4 | | | | |

 

| 5 | Surprise me. | | | |

 

我们来处理侧面列的方式与主列。首先,使用regexextract函数从中搜索并返回有效值side列。

 

regexextract([Side], "(?i)injera")

 

创建Vegetables 自定义列:

 

regexextract([Side],

 

"(?i)(grilled vegetables)")

 

要获得输出:

 

| Response ID | Side |Injera | Vegetables |

 

|-------------|--------------------|--------|--------------------|

 

| 1 | injera | injera | |

 

| 2 | grilled vegetables| | grilled vegetables |

 

| 3 | | | |

 

| 4 | Grilled Vegetables| | Grilled Vegetables |

 

| 5 | | | |

 

然后,使用coalesce 函数和lower函数要处理人们放置了部分、多个或没有有效side选项的情况,并将所有值转换为小写:

 

创建side(clean)自定义列:

 

lower(coalesce([Injera],[Vegetables], ""))

 

得到

 

Response ID | Side |Injera | Vegetables | Side(Clean) |

 

|-------------|--------------------|--------|--------------------|--------------------|

 

| 1 | injera | injera | | injera |

 

| 2 | grilled vegetables| | grilled vegetables | grilledvegetables |

 

| 3 | | | | |

 

| 4 | Grilled Vegetables| | Grilled Vegetables | grilledvegetables |

 

| 5 | | | | |

 

组合来自不同列的值

 

最后,我们希望通过检查每个场景来生成完整的订单:

 

如果主(干净)和侧面(干净)两者都包含一个有效的选项,然后返回“main

 

     with side”。

 

如果只有一个有效选项,则返回“main only”或“side

 

     only”。

 

如果没有有效的选项,请将订单留空(返回空字符串)。

 

要检查列是否为非空,我们将使用isempty函数.

 

例如,检查Main(clean)为空:

 

isempty([Main

 

(Clean)])

 

检查是否Main(clean)和Side(clean)是二者都blank,可以使用以及:

 

isempty([Main

 

(Clean)]) AND isempty([Side (Clean)])

 

isempty目前只在另一个函数中工作,所以我们需要把每一张支票放在case函数。我们暂时将占位符文本作为输出:

 

case(

 

    (isempty([Main (Clean)]) ANDisempty([Side (Clean)])), "",

 

    isempty([Side (Clean)]),"main only",

 

    isempty([Main (Clean)]),"side only",

 

"main with side"

 

)

 

请注意,Case的顺序很重要,因为:

 

这个case函数按顺序计算每个表达式,并在第一找到有效案例。

 

如果将第一个大小写替换为第二个大小写,表达式将确认这一点side(clean)为空并立即返回“main only”,而不必检查是否main(clean)也是空的。

 

最后,为了填写每位客人的最终订单,我们将使用concat函数将值从main(clean)和side(clean)其他单词(包括空格)。

 

创建命令使用列:

 

case(

 

    (isempty([Main (Clean)]) ANDisempty([Side (Clean)])), "",

 

    isempty([Side (Clean)]),concat([Main (Clean)], " only"),

 

    isempty([Main (Clean)]),concat([Side (Clean)], " only"),

 

concat([Main (Clean)], " with", [Side (Clean)])

 

)

 

总的来说,这将为我们提供一组如下格式的列(向右滚动可查看完整的表):

 

| Response ID | Main | Side | Main (Clean) | Side (Clean) | Order |

 

|-------------|-------------------------------------|--------------------|-----------------|--------------------|---------------------------------------|

 

| 1 | beef tibs | injera | beef tibs | injera | beef tibs with injera |

 

| 2 | chickpea stew | grilled vegetables |chickpea stew | grilled vegetables |chickpea stew with grilled vegetables |

 

| 3 | BEEF TIBS WITHCHICKPEA STEW PLEASE | | beef tibs | | beef tibs only |

 

| 4 | | GrilledVegetables | | grilledvegetables | grilled vegetables only |

 

| 5 | Surprise me. | | | | |

 

用空白值标记行

 

假设我们要添加一个名为跟进?跟踪缺少有效主、一个边或两者的订单。这意味着我们需要检查Order, Main

 

(Clean), 或者 Side

 

(Clean) 是空白的。

 

我们可以把isempty功能和或者 operator如果三列中的任何一列为空,则返回“yes”;如果所有列都用有效数据填充,则返回“no”。

 

创建跟进?使用:

 

case(( isempty([Order])

 

    OR isempty([Main (Clean)])

 

    OR isempty([Side (Clean)])), "yes", "no")

 

最终结果(向右滚动可查看完整表格):

 

| Response ID | Main | Side | Order | Follow up? |

 

|-------------|-------------------------------------|-------------------------|---------------------------------------|------------|

 

| 1 | beef tibs | injera | beef tibs with injera | no |

 

| 2 | chickpea stew | grilled vegetables | chickpea stew with grilled vegetables | no |

 

| 3 | BEEF TIBS WITH CHICKPEA STEW PLEASE | | beef tibs | yes |

 

| 4 | | vegetables | grilled vegetables | yes |

 

| 5 | Surprise me. | |             

 

 

 

最佳实践和技巧

 

在本教程中,每次需要提取、组合或标记文本数据时,我们都会创建一个新的自定义列。我们还结合了更简单的函数(例如lower和isempty)其他功能。通常,我们建议每次使用带有多个参数的函数时创建一个新的自定义列(例如case,regexextract和coalesce),因为:

 

您可以确认表达式是否按预期工作。

 

逻辑更容易阅读和更新。

 

如果您习惯于使用其他工具(如SQL、电子表格或Python)中的函数,请查看相关功能自定义表达式文档中的部分。例如,您可以学习如何使用case的相关函数.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值