Metabase学习教程:提问-7
admin
2024-02-08 22:14:21

清理和格式化文本

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

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

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

Response ID | Main                                | Side                    |

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

| 1           | beef tibs                           | injera                  |

| 2           | chickpea stew                       | grilled vegetables      |

| 3           | BEEF TIBS WITH CHICKPEA STEW PLEASE |                         |

| 4           |                                     | Grilled Vegetables      |

| 5           | Surprise me.                        |                         |

我们希望:

  1. 整理并结合主食和副食,这样我们就可以数出最受欢迎的饭菜了。
  2. 处理在某些方面无效的响应(例如多个电源,或者菜单上不存在的电源)。
  3. 跟踪提交了缺少信息的回复的客人。

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

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 only                        | yes        |

| 4           |                                     | Grilled Vegetables      | grilled vegetables only               | yes        |

| 5           | Surprise me.                        |                         |                                       | yes        |
 

搜索和提取文本

我们假设唯一有效的主要选择是牛肉和鹰嘴豆炖菜。我们可以使用  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 WITH CHICKPEA 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 WITH CHICKPEA 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选项的情况,并将所有值转换为小写:

创建sideclean自定义列:

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

得到

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

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

| 1           | injera             | injera |                    | injera             |

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

| 3           |                    |        |                    |                    |

| 4           | Grilled Vegetables |        | Grilled Vegetables | grilled vegetables |

| 5           |                    |        |                    |                    |

组合来自不同列的值

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

  • 如果主(干净)侧面(干净)两者都包含一个有效的选项,然后返回“main with side”。
  • 如果只有一个有效选项,则返回“main only”或“side only”。
  • 如果没有有效的选项,请将订单留空(返回空字符串)。

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

例如,检查Mainclean为空:

isempty([Main (Clean)])

检查是否MaincleanSideclean二者都blank,可以使用以及:

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

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

case(

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

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

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

"main with side"

)

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

  • 这个case函数按顺序计算每个表达式,并在第一找到有效案例。
  • 如果将第一个大小写替换为第二个大小写,表达式将确认这一点sideclean为空并立即返回“main only”,而不必检查是否mainclean也是空的。

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

创建命令使用列:

case(

    (isempty([Main (Clean)]) AND isempty([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 WITH CHICKPEA STEW PLEASE |                    | beef tibs       |                    | beef tibs only                        |

| 4           |                                     | Grilled Vegetables |                 | grilled vegetables | grilled vegetables only               |

| 5           | Surprise me.                        |                    |                 |                    |                                       |

用空白值标记行

假设我们要添加一个名为跟进?跟踪缺少有效主、一个边或两者的订单。这意味着我们需要检查OrderMain (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.                        |                         |              

最佳实践和技巧

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

  • 您可以确认表达式是否按预期工作。
  • 逻辑更容易阅读和更新。

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

相关内容

热门资讯

赤水性价比粮食酒推荐:2025... 赤水性价比粮食酒推荐:2025年酱香酒选购全攻略 一、开篇背景与市场痛点 2025年的赤水河流域酒类...
非白酒板块11月19日跌0.3... 证券之星消息,11月19日非白酒板块较上一交易日下跌0.33%,*ST椰岛领跌。当日上证指数报收于3...
以运河文化赋能产业发展|古贝春... 11月17日至19日,以“新质开新局,聚力创未来”为主题的2025年第六届中国白酒黄淮核心产区高质量...
深夜小酌的灵魂搭档:油炝脆骨,... 油炝脆骨是一道充满锅气与烟火气息的家常菜,以其爽脆的口感和浓郁的香辣风味深受许多人喜爱。这道菜的制作...
初中毕业新征程:为什么西点烘焙... 站在初中毕业的人生路口,许多女孩都在思考:哪条路能通往一个既美好又独立的未来?如果有一条道路,能将女...