I'm creating a Leaflet widget in R using the following code
m <- leaflet(map_data_wgs84) %>% addTiles() %>% addCircles(popup = (paste(sep="<br/>", as.character(map_data_wgs84$MEMBER_REF), map_data_wgs84$Name)))
saveWidget(m, file="c://software//members.html")
I want a popup that palaces an ID number and name separated by a line break. However when I run the saveWidget command I get the following error
Error in gsub("</", "\\u003c/", payload, fixed = TRUE) :
input string 1 is invalid UTF-8
which is because of the <br/>
separator.
What am I doing wrong here?
thanks
UPDATE:
it would appear it is not the <br/>
separator but rather character(s) in the map_data_wgs84$Name column. These 12000 records are pulled from a contact database before mapping.
I suspect I need some way to make the characters clean for use in Leaflet with something like htmlEscaoe however I cant figure out how to use this within paste. This doesnt work because htmlEscape is parsed as a string:
addCircles(popup = paste(as.character(map_data_wgs84$MEMBER_REF), ~htmlEscape(map_data_wgs84$Name), sep=","))
For for a MEMBER_REF of 56202 the popup becomes:
56202,htmlEscape(map_data_wgs84$Name)
To resolve the UTF-8 error, I followed three steps:
After reading How to identify/delete non-UTF-8 characters in R, I used base::Encoding()
to manually encode the values with the Name
column to UTF-8. I then used base::iconv()
to replace all non UTF-8 characters with an empty space;
I manually placed the line break element - <br>
rather than <br/>
- inside of the sep
argument within the paste()
function when creating the popup within the markers of the leaflet object; and
To be safe, I used htmltools::htmlEscape()
inside of the text vectors used inside of paste()
.
All together, I was able to export that object as an HMTL file. All packages versions are copied down below in the Session Info section.
# load necessary packages
library( htmltools )
library( htmlwidgets )
library( leaflet )
# create data
map_data_wgs84 <-
data.frame( MEMBER_REF = "Popup"
, Name = "Th\x86e birthplace of R."
, Long = 174.768
, Lat = -36.852
, stringsAsFactors = FALSE )
# pre-processing
# ensure that all characters in the `Name` column
# are valid UTF-8 encoded
# Thank you to SO for this gem
# https://stackoverflow.com/questions/17291287/how-to-identify-delete-non-utf-8-characters-in-r
Encoding( x = map_data_wgs84$Name ) <- "UTF-8"
# replace all non UTF-8 character strings with an empty space
map_data_wgs84$Name <-
iconv( x = map_data_wgs84$Name
, from = "UTF-8"
, to = "UTF-8"
, sub = "" )
# check work
map_data_wgs84$Name # [1] "The birthplace of R."
# create leaflet object
my.map <-
leaflet( data = map_data_wgs84 ) %>%
addTiles() %>%
addCircles( lng = ~Long
, lat = ~Lat
, popup = paste( as.character( map_data_wgs84$MEMBER_REF )
, htmlEscape( map_data_wgs84$Name )
, sep = "<br>" )
, radius = 50 )
# export leaflet object as HMTL file
saveWidget( widget = my.map
, file = "mywidget.html" )
# end of script #
R version 3.5.1 (2018-07-02)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS High Sierra 10.13.6
Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] leaflet_2.0.1 htmlwidgets_1.2 htmltools_0.3.6
loaded via a namespace (and not attached):
[1] Rcpp_0.12.18 digest_0.6.15 later_0.7.3 mime_0.5
[5] R6_2.2.2 xtable_1.8-2 jsonlite_1.5 magrittr_1.5
[9] promises_1.0.1 tools_3.5.1 crosstalk_1.0.0 shiny_1.1.0
[13] httpuv_1.4.5 yaml_2.1.19 compiler_3.5.1
I saw this solution in another post (sorry, lost the link!) which use sprintf to combine text and variables and then using htmltools within lapply to make the content HTML-happy! In this particular I created the following list:
labels <- sprintf(
"<strong>%s</strong><br/>%o<br/>%s",
map_data$Name, map_data$Events, map_data$member_ref
) %>% lapply(htmltools::HTML)
and then called this from leaflet:
my_map <- leaflet(map_data_wgs84) %>% addTiles() %>% addCircles(popup = labels)
Hope this helps someone else!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With