Below is the reproducible code which needs to be pasted in PowerBI R script visualization.
I'm making some customizations to the default process_map object
.
The visual works on my current desktop but gives out error when published to PowerBI Web.
# The following code to create a dataframe and remove duplicated rows is always executed and acts as a preamble for your script:
# dataset <- data.frame(Column1)
# dataset <- unique(dataset)
# Paste or type your script code here:
library(bupaR)
library(DiagrammeR)
library(tidyverse)
library(lubridate)
# convert to proper date
processMap <- patients %>%
process_map(sec = performance(median, "hours")
,type = frequency("relative_case")
,type_edges = frequency("absolute_case")
,rankdir = "LR"
,layout = layout_pm(edge_weight = TRUE)
,fixed_edge_width = F
,render = F
)
# customisation(label, color, font)
processMap$nodes_df$label <- stringr::str_replace_all(processMap$nodes_df$label, c('ARTIFICIAL_START' = 'Start', 'ARTIFICIAL_END' = 'End'))
processMap$nodes_df$color <- stringr::str_replace_all(processMap$nodes_df$color, c('chartreuse4' = '#769e00', 'brown4' = '#7a0f2d'))
processMap$nodes_df$fontcolor <- stringr::str_replace_all(processMap$nodes_df$fontcolor, c('chartreuse4' = '#769e00', 'brown4' = '#7a0f2d'))
processMap$nodes_df$fontname <- stringr::str_replace_all(processMap$nodes_df$fontname, c('Arial' = 'Calibri'))
processMap$edges_df$fontname <- stringr::str_replace_all(processMap$edges_df$fontname, c('Arial' = 'Calibri'))
# change edge with
processMap$edges_df$penwidth <- scales::rescale(processMap$edges_df$penwidth, to = c(0.5, 4))
# custom duration edges
edges_label <- processMap$edges_df$label
tmp <- regmatches(edges_label, gregexpr("\\(.*?\\)", edges_label))
tmp <- gsub("[\\(\\)]", "", tmp)
tmp <- stringr::str_replace_all(tmp, c('character0' = '0', ' hours'=''))
tmp <- as.numeric(tmp)*60*60
tmp <- lubridate::as.duration(tmp)
tmp <- regmatches(tmp, gregexpr("\\(.*?\\)", tmp))
tmp <- gsub("[\\(\\)]", "", tmp)
edges_label_duration <- stringr::str_replace_all(tmp, c('character0' = '<1 hour'))
edges_label_count_absolute_case <- gsub("\n.*","",edges_label)
edges_label_clean <- paste0(edges_label_count_absolute_case, '\n',edges_label_duration)
# remove those which should have no hour()
correct_label <- gsub("\n.*","",edges_label_clean[!grepl("hour", edges_label)])
edges_label_clean[!grepl("hour", edges_label)] <- correct_label
# assign to process object
processMap$edges_df$label <- edges_label_clean
DiagrammeR::export_graph(graph = processMap, file_type = 'png', file_name = 'processMap.png')
Below is the visual output in PowerBI desktop
When published to the PowerBI portal, it gives the following error
Error in if (any(ind)) Encoding(x[ind]) <- "bytes" :
missing value where TRUE/FALSE needed
In addition: Warning message:
Prefixing `UQ()` with the rlang namespace is deprecated as of rlang 0.3.0.
Please use the non-prefixed form or `!!` instead.
# Bad:
rlang::expr(mean(rlang::UQ(var) * 100))
# Ok:
rlang::expr(mean(UQ(var) * 100))
# Good:
rlang::expr(mean(!!var * 100))
rlang's on desktop is rlang_0.4.10
while the PowerBI Web has a rlang_0.3.0
I ended up re-writing the customisation code so that there's no function
within a function
which is referenced by the error code below
# Bad:
rlang::expr(mean(rlang::UQ(var) * 100))
I suspect the related function is this one
regmatches(edges_label, gregexpr("\\(.*?\\)", edges_label))
Couldn't really definitively say it's the case but anyways the updated code below generates no more error when published to PowerBI service/web.
library(bupaR)
library(DiagrammeR)
library(tidyverse)
library(lubridate)
# convert to proper date
processMap <- patients %>%
process_map(sec = performance(median, "hours")
,type = frequency("relative_case")
,type_edges = frequency("absolute_case")
,rankdir = "LR"
,layout = layout_pm(edge_weight = TRUE)
,fixed_edge_width = F
,render = F
)
# customisation(label, color, font)
processMap$nodes_df$label <- stringr::str_replace_all(processMap$nodes_df$label, c('ARTIFICIAL_START' = 'Start', 'ARTIFICIAL_END' = 'End'))
processMap$nodes_df$color <- stringr::str_replace_all(processMap$nodes_df$color, c('chartreuse4' = '#769e00', 'brown4' = '#7a0f2d'))
processMap$nodes_df$fontcolor <- stringr::str_replace_all(processMap$nodes_df$fontcolor, c('chartreuse4' = '#769e00', 'brown4' = '#7a0f2d'))
processMap$nodes_df$fontname <- stringr::str_replace_all(processMap$nodes_df$fontname, c('Arial' = 'Calibri'))
processMap$edges_df$fontname <- stringr::str_replace_all(processMap$edges_df$fontname, c('Arial' = 'Calibri'))
# change edge with
processMap$edges_df$penwidth <- scales::rescale(processMap$edges_df$penwidth, to = c(0.5, 4))
# custom duration edges
edges_label <- processMap$edges_df$label
# extract within bracket
tmp <- stringr::str_extract(string = edges_label,
pattern = "(?<=\\().*(?=\\))")
tmp <- stringr::str_replace_all(tmp, c(' hours'=''))
tmp[is.na(tmp)] <- '0'
tmp <- as.numeric(tmp)*60*60
tmp <- lubridate::as.duration(tmp)
tmp <- stringr::str_extract(string = tmp,
pattern = "\\(.*?\\)")
tmp[is.na(tmp)] <- '(<1 hour)'
edges_label_duration <- tmp
edges_label_count_absolute_case <- gsub("\n.*","",edges_label)
edges_label_clean <- paste0(edges_label_count_absolute_case, '\n',edges_label_duration)
# remove those which should have no hour()
correct_label <- gsub("\n.*","",edges_label_clean[!grepl("hour", edges_label)])
edges_label_clean[!grepl("hour", edges_label)] <- correct_label
# assign to process object
processMap$edges_df$label <- edges_label_clean
DiagrammeR::export_graph(graph = processMap, file_type = 'png', file_name = 'processMap.png')