【问题标题】:Invalid UTF-8 Error when saving Leaflet Widget in R在 R 中保存 Leaflet Widget 时出现无效的 UTF-8 错误
【发布时间】:2018-12-26 02:53:41
【问题描述】:

我正在使用以下代码在 R 中创建一个 Leaflet 小部件

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")

我想要一个弹出窗口,其中包含由换行符分隔的 ID 号和名称。但是,当我运行 saveWidget 命令时,出现以下错误

Error in gsub("</", "\\u003c/", payload, fixed = TRUE) : 
  input string 1 is invalid UTF-8

这是因为&lt;br/&gt; 分隔符。

我在这里做错了什么?

谢谢

更新: 它似乎是 不是 &lt;br/&gt; 分隔符,而是 map_data_wgs84$Name 列中的字符。这 12000 条记录是在映射之前从联系人数据库中提取的。

我怀疑我需要一些方法来使字符干净,以便使用 htmlEscaoe 之类的东西在 Leaflet 中使用,但是我不知道如何在粘贴中使用它。这不起作用,因为 htmlEscape 被解析为字符串:

addCircles(popup = paste(as.character(map_data_wgs84$MEMBER_REF), ~htmlEscape(map_data_wgs84$Name), sep=","))

对于 56202 的 MEMBER_REF,弹出窗口变为:

56202,htmlEscape(map_data_wgs84$Name)

【问题讨论】:

    标签: r leaflet


    【解决方案1】:

    我在另一篇文章中看到了这个解决方案(抱歉,链接丢失了!)它使用sprintf 组合文本和变量,然后在lapply 中使用htmltools 使内容HTML 快乐!在这个特殊的情况下,我创建了以下列表:

    labels <- sprintf(
      "<strong>%s</strong><br/>%o<br/>%s",
      map_data$Name, map_data$Events, map_data$member_ref
    ) %>% lapply(htmltools::HTML)
    

    然后从传单中调用它:

    my_map <- leaflet(map_data_wgs84) %>% addTiles() %>% addCircles(popup = labels)
    

    希望这对其他人有帮助!

    【讨论】:

      【解决方案2】:

      概述

      为了解决 UTF-8 错误,我遵循了三个步骤:

      1. 读完How to identify/delete non-UTF-8 characters in R后,我使用base::Encoding()Name列的值手动编码为UTF-8。然后我使用base::iconv() 将所有非UTF-8 字符替换为空格;

      2. 在传单对象的标记内创建弹出窗口时,我手动将 line break element - &lt;br&gt; rather than &lt;br/&gt; - 放置在 sep 函数内的 paste() 参数中;和

      3. 为了安全起见,我在paste() 内部使用的文本向量内部使用了htmltools::htmlEscape()

      总的来说,我能够将该对象导出为 HMTL 文件。所有软件包版本都复制到下方的“会话信息”部分中。

      可重现的示例

      # 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 
      

      【讨论】:

      • 感谢指针@cristian-e-nuno(和可重现的示例)-进一步试验导致错误的字符实际上位于来自数据库的 map_data_wgs84$Name 列中。但是我无法弄清楚如何在粘贴中使用 ~htmlEscape 。任何想法都失败了: addCircles(popup = paste(as.character(map_data_wgs84$MEMBER_REF), ~htmlEscape(map_data_wgs84$Name), sep=","))
      • @Miksmith,您能否举例说明该列中存储的字符类型?这将帮助我和其他人进一步帮助你。我也不确定map_data_wgs84 是空间多边形数据框、sf 还是可能会或可能不会影响我们的数据框。
      • @Miksmith,您介意复制并粘贴您的新错误代码吗?随时修改您的问题以反映您的新情况。
      • @cristian-e-nuno 非常感谢 - 更新了原来的 Q
      • @cristian-e-nuno PS 有空间列(纬度,经度),因为它们是使用英国国家电网的 spTransform 转换的。但是,名称列只是一个文本字符串(联系人姓名)
      猜你喜欢
      • 2019-08-21
      • 2015-12-06
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-03
      相关资源
      最近更新 更多