使用 Tableau Prep 分析医院床位使用情况
医院满员会造成问题,但资源过多也同样会造成问题。务必要从床位即资源的角度来理解医院床位。但是,数据通常是从患者的角度进行存储的。我们如何才能获取相关数据,了解患者何时占用床位并确定床位使用情况?
注意:为了完成这些教程中的任务,您需要安装 Tableau Prep 并根据需要安装 Tableau Desktop:
若要安装 Tableau Prep 和 Tableau Desktop,请参见 Tableau Desktop 和 Tableau Prep 部署指南(链接在新窗口中打开)。否则,您可以下载 Tableau Prep(链接在新窗口中打开) 和 Tableau Desktop(链接在新窗口中打开) 免费试用版。
您还需要下载三个数据文件。建议将这些文件保存在 我的 Tableau Prep 存储库 > Datasources 文件夹中。
- Beds.xlsx(链接在新窗口中打开)
- Hours.xlsx(链接在新窗口中打开)
- Patient Beds.xlsx(链接在新窗口中打开)
数据
对于我们的四个床位 A、B、C 和 D,我们将跟踪哪个患者占用了床位,以及他们占用床位的开始和结束时间。数据看起如下所示:
初步分析
如果我们将此数据引入 Tableau Desktop,我们可以创建一个甘特图来显示患者何时占用床位。
这是一种有用的视觉元素。我们可以看到,床位 A 和 B 的使用间隔时间很短,但床位 C 使用得非常少。床位 D 的患者没有结束时间,但我们将利用一些计算来解决该情况。这为我们提供了一个关于床位使用情况的视觉概览。
但是,如果我们想要计算床位空置的小时数,该怎么办?或者,如果我们要比较实施新政策前后的开放床位时间,该怎么办?通过采用当前结构方式的数据无法轻松地达到目的。
所需的数据结构
通过创建一些非常基本的数据集并在 Tableau Prep 中将其合并,我们可以将此数据集修改为允许我们执行更深入分析并创建更有用的可视化项的形式。
在进入 Tableau Prep 之前,让我们回顾一下,想一想我们需要创建什么才能回答以下问题:“每个床位空置了多少小时?”
我们需要能够查看每小时的每个床位,并了解是否有患者占用床位。目前,数据仅仅是患者何时占用床位;我们还未向 Tableau 提供有关空置小时数的信息。
为了创建包含所有床位和所有小时的完整矩阵,我们将创建两个新数据集。一个数据集是床位的列表(A、B、C、D),另一个数据集是小时的列表(1、2、3、…、23、24)。通过执行交叉联接(将一个数据集中的每一行与另一个数据集中的每一行联接),我们将最终获得床位和小时的每种可能组合。
Beds.xlsx 数据集看起来如下所示: | Hours.xlsx 数据集看起来如下所示: | 而交叉联接的结果看起来如下所示: |
接着,我们将引入“Patient Beds”(患者床位)信息,以是否有特定患者的形式标记每个床位-小时组合。我们最终会得到一个数据集,该数据集中每个床位-小时组合占一行,并且,如果患者占用了床位,则包含患者的编号及开始和结束时间。Null 值指明床位未被占用。
利用此结构中的数据,我们可以执行像这样的分析,让我们能够像调查患者床位一样轻松地调查未占用的床位。
重构数据
那么如何使用 Tableau Prep 达到该目的?我们将分两个部分构建流程,首先构建“Bed Hours”(床位小时)矩阵,然后将其与“Patient Beds”(患者床位)数据合并。确保下载全部三个 Excel 文件(Beds.xlsx、Hours.xlsx 和 Patient Beds.xlsx)以便继续操作。
床位小时矩阵
首先,我们将连接到 Beds.xlsx 文件。
打开 Tableau Prep。
从开始屏幕中,单击“连接到数据”。
在“连接”窗格上,单击“Microsoft Excel”。导航到 Beds.xlsx 的保存位置,并单击“打开”。
“Beds”(床位)工作表应会自动显示在“流程”窗格中。
提示:有关连接到数据的详细信息,请参见连接到数据(链接在新窗口中打开)。
接着,我们需要创建一个可用于与“Hours”(小时)数据集执行交叉联接的字段。我们将添加一个仅仅为值 1 的计算。
在“流程”窗格中,选择“Beds”(床位)并单击建议的“清理步骤”。
随我们刚刚添加的“清理”步骤一起,“配置”窗格将出现。单击工具栏中的“创建计算字段”。
将字段命名为“Cross Join”(交叉联接),并输入值 1。
“数据”网格应会更新为显示数据的当前状态。
现在,我们将使用“Hours”(小时)数据集重复该过程。
在“连接”窗格上,单击“添加连接” 按钮以添加另一个数据连接。
选择“Microsoft Excel”,然后选择 Hours.xlsx 文件并单击“打开”。
在“流程”窗格中,选择“Hours”(小时),并单击建议的“清理步骤”将其添加到流程。
通过“配置”窗格中的工具栏创建一个名为“Cross Join”(交叉联接)的计算字段,并输入值 1。
两个数据集现在有一个共同字段“Cross Join”(交叉联接),因此可以联接。
通过将“Clean 2”(清理 2)拖到“Clean 1”(清理 1)并放在“联接”选项上来联接两个清理步骤。
在下面的“联接配置”中,联接配置应会自动填充。
由于我们将两个字段都命名为“Cross Join”(交叉联接),因此 Tableau Prep 自动将它们识别为共同字段,并创建适当的“已应用联接子句”。
默认“联接类型”为内部联接,正是我们所需要的。
此联接会将“Beds”(床位)中的所有行与“Hours”(小时)中的所有行匹配,如“数据”网格中所示。
A. 联接子句
B. 联接类型
C. 数据网格结果
提示:有关联接的详细信息,请参见联接数据(链接在新窗口中打开)。
我们不再需要“Cross Join”(交叉联接)字段,因此可以将这些字段移除。
在“流程”窗格中,选择“Join 1”(联接 1),单击加号 图标,并选择“添加清理步骤”。
选择字段“Cross Join-1”(交叉联接-1)和“Cross Join”(交叉联接),并单击“移除字段”。
双击“Clean 3”(清理 3)标签,并将该步骤重命名为“Bed Hour Matrix”(床位小时矩阵)。
我们现在有了“Bed Hour Matrix”(床位小时矩阵)数据集,其中包含所有床位和所有小时,并且我们已完成构建数据集的第一部分。
患者床位使用
第二部分是引入患者床位使用情况。首先,我们将连接到数据。
在“连接”窗格上,单击“添加连接” 按钮以添加另一个数据连接。
选择“Microsoft Excel”,然后选择 Patient Beds.xlsx 文件,并单击“打开”。
在“流程”窗格中,选择“Patient Beds”(患者床位),然后单击建议的“清理步骤”将其添加到流程。
由于“床位小时矩阵”文件基于小时,但“患者床位”基于实际时间,因此我们需要从“患者床位”开始和结束时间中提取小时。此外,对于结束时间,我们想要确保,如果患者在一天结束时(午夜,24 时)仍然占用床位,则我们指明床位被占用,即使数据集中没有结束时间也是如此。我们将在此新步骤中添加计算字段。
在工具栏中,单击“创建计算字段”。
将字段命名为“Start Hour”(开始小时)。对于计算,输入
DATEPART('hour',[Start Time])
。创建另一个名为“End Hour”(结束小时)的计算字段。对于计算,输入
IFNULL(DATEPART('hour',[End Time]), 24)
。
这将获取开始时间的小时并将其提取出来。因此,“1/1/18 9:35 AM”将变为“9”。
DATEPART
部分获取结束时间的小时。IFNULL
部分将为任何缺少的结束时间分配结束时间 24 时(午夜)。
现在我们已准备好将患者床位使用情况联接到“Bed Hour Matrix”(床位小时矩阵)。与我们之前进行的操作相比,此联接操作更为复杂一些。内部联接将只会返回两个数据集中都存在的值。由于我们想要确保保留所有床位-小时槽位,而不管患者是否占用床位,因此我们需要执行左联接。此将生成许多 null 值,但这是适当的。
我们还需要匹配床位-小时槽位被一名(或多名)患者占用的时间。因此,除了匹配患者占用的床位外,我们还需要考虑时间。“Bed Hour Matrix”(床位小时矩阵)数据集只有“Hour”(小时)字段,而“Patient Beds”(患者床位)数据集有“Start Hour”(开始小时)和“End Hour”(结束小时)。我们使用一些基本逻辑来确定是否应将患者分配到给定床位-小时槽位:如果其开始小时小于或等于 (<=) 床位-小时槽位,并且其结束小时大于或等于 (>=) 床位-小时槽位,则患者被视为占用床位。
因此,需要三个联接子句来将这两个数据集相应地匹配在一起。
将“Clean 3”(清理 3)步骤与“Bed Hour Matrix”(床位小时矩阵)步骤联接。
在“已应用联接子句”区域中,默认值应为“Hour = End Hour”。单击联接子句,将运算符从“=”改为“<=”。
单击“已应用联接子句”区域右上角的加号 按钮,以添加另一个联接子句。将其设置为“Hour >= Start Hour”
为“Bed = Hospital Bed”添加第三个联接子句。
在“联接类型”部分,单击“Bed Hour Matrix”(床位小时矩阵)旁边图形的无阴影区域,将联接类型更改为“左”联接。
注意:如果将“Bed Hour Matrix”(床位小时矩阵)拖到“Clean 3”(清理 3),而不是相反,则通过使用右联接(而不是左联接)可以获得期望的结果。对于联接的方向,拖动步骤的顺序很重要。联接子句也将按相反顺序 — 一定要保持比较小时的正确逻辑。
数据现在已联接,但我们应从联接中清理一些构件,并确保字段保持整齐。我们不再需要“Start Hour”(开始小时)和“End Hour”(结束小时)。“Hospital Bed”(医院床位)和“Bed”(床位)也是多余的。最后,“Patient”(患者)字段中的值 null 实际上表示床位未被占用。
在“流程”窗格中,添加一个清理步骤以便能对联接的数据进行整理。
按住 Ctrl 单击(在 Mac 上按住 Command 单击)以多选方式选择字段“End Hour”(结束小时)、“Start Hour”(开始小时)和“Hospital Bed”(医院床位),然后在工具栏中单击“移除字段”。
在“Patient”(患者)字段配置卡上,双击“null”值并键入“Unoccupied”(未占用)。
我们现在有了每个床位-小时占一行的数据结构;如果在该小时期间有患者占用床位,则我们也有了患者信息。余下的工作就是添加输出步骤和生成数据集本身。
在“流程”窗格中,选择“Clean 4”(清理 4),单击加号 图标,并选择“添加输出”。
在“输出”窗格中,将“输出类型”更改为 .csv,然后单击“浏览”。
为名称输入“Bed Hour Patient Matrix”(床位小时患者矩阵),并在单击“接受”保存之前选择所需的位置。
单击窗格底部的“运行流程” 按钮生成输出。在状态对话框中单击“完成”关闭对话框。
提示:有关输出和运行流程的详细信息,请参见保存和共享工作(链接在新窗口中打开)。
最终流程应如下所示:
Tableau Desktop 中的分析
若要在继续执行本教程之前安装 Tableau Desktop,您可以下载免费试用版。
现在我们有了采用所需结构的数据集,我们可以执行比用原始数据更深入的分析。
打开 Tableau Desktop。在“连接”窗格中,选择“文本文件”,导航到 Bed Hour Patient Matrix.csv 文件,并单击“打开”。
在“数据源”选项卡上,默认情况下数据应出现在画布中。单击“Sheet 1”(工作表 1)。
在“数据”窗格中,将“Hour”(小时)拖到分隔“度量”和“维度”的线上方,将其设为离散维度。
将“Bed”(床位)拖到“行”功能区,并将“Hour”(小时)拖到“列”功能区。
将“Patient”(患者)拖到“颜色”功能区。
格式设置为可选,但可以帮助使图示更易于理解。
单击“颜色”功能区,并选择“编辑颜色”。
在左侧的区域中,选择“Unoccupied”(未占用)。从右侧的下拉列表中,选择“西雅图灰”调色板。
选择第四个最浅的灰色,并单击“确定”。
再次单击“颜色”功能区,然后单击“边框”下拉列表。选择最右侧的第二个灰色选项。
在工具栏中,通过“大小”下拉列表将“标准”更改为“适合宽度”。
单击“设置格式”菜单,然后单击“边框”。
对于“行分隔符”,单击“区”下拉列表并选择一种非常浅的灰色。
将“级别”滑块调整到第二个刻度标记。
为“列分隔符”重复这些步骤。将“区”颜色设置为浅灰色,并将“级别”调整到第二个刻度标记。
双击底部的工作表标签,并将其重命名为“Bed Use by Hour”(按小时列出的床位使用情况)。
此视图让我们能快速查看给定床位何时处于占用或空置状态。
但我们可以更进一步,并计算每个床位未被占用的小时数。
单击底部的新工作表标签 打开一个空白工作表。
将“Patient”(患者)拖到“行”。
将“Hour”(小时)拖到“列”。右键单击“Hour”(小时)胶囊打开菜单。选择“度量”>“计数”。
将“Patient”(患者)字段的另一个副本从“数据”窗格拖到“颜色”功能区。
右键单击轴,并选择“编辑轴”。将标题更改为“Hours”(时数)并关闭对话框。
将工作表标签重命名为“Bed Hours by Patient.”(患者占用床位时数)。
此视图使我们能够确定我们有多少未占用床位时数,而这是使用原始数据集做不到的。您可以创建哪些其他图标或仪表板?既然您的数据结构正确,不妨试一下。
总结和资源
为了使用 Tableau Prep 构建此数据结构,我们需要执行以下操作:
针对我们想要分析的各个方面(本例中为床位和小时)构建数据集。
交叉联接这些数据集,创建一个包含床位和小时每种可能组合的“Bed Hour Matrix”(床位小时矩阵)数据集。
将“Bed Hour Matrix”(床位小时矩阵)与“Patient Bed”(患者床位)数据联接,同时确保联接保留所有床位-槽位小时,并且联接子句恰当地将患者床位数据与床位-小时槽位匹配。
我们使用以下计算来创建可以联接的字段。第二个和第三个计算从原始日期时间字段中提取小时信息。
Cross Join(交叉联接)=
1
此计算只是为每一行分配值 1
Start Hour(开始小时)=
DATEPART('hour',[Start Time])
这将获取开始时间的小时并将其提取出来。因此,“1/1/18 9:35 AM”将变为“9”。
End Hour(结束小时)=
IFNULL(DATEPART('hour',[End Time]), 24)
我们可以使用
DATEPART('hour',[End Time])
,就像我们为“Start Time”(开始时间)所做的一样。这将获取结束时间的小时并将其提取出来。因此,“1/1/18 4:34 AM”将变为“4”。但我们想要指明仍被占用(没有结束时间)的患者床位在使用中,而不是空置。为此,我们将使用
IFNULL
函数为任何缺少的结束时间分配结束时间 24 时(午夜)。如果第一个参数DATEPART('hour',[End Time])
为 null,则计算将改为返回“24”。
注意:想要检查您的工作?下载 Tableau Prep 打包流程文件 (Hospital Beds.tflx(链接在新窗口中打开)) 和 Tableau Desktop 打包工作簿文件 (Hospital Beds.twbx(链接在新窗口中打开))。
资源:需要更多培训?参加现场培训(链接在新窗口中打开)课程。想知道我们涵盖的功能?请查看 Tableau Prep 联机帮助中的其他主题。在寻找其他资源?Master Tableau Prep with this list of learning resources(利用此学习资源清单掌握 Tableau Prep)(链接在新窗口中打开)博文正适合于您。