在 highchart 地图中为动态变量格式化工具提示,一些用逗号,另一些用百分比

Format tooltip in highchart map for dynamic variables, some with commas and others with percents

我编写了一个函数来将数据提取到 highcharter cloropleth 地图中。我很难弄清楚如何根据它们是计数(需要带逗号且没有小数位的格式)还是百分比(需要乘以 100 和 % 符号)来格式化进入地图的值添加为前缀)

该函数接受一个数据帧 x 并选择与分配给所需变量的标签相对应的变量,该变量作为 y 提供。在此代表中,您可以将“计数”更改为“百分比”以更改地图。在我的实际仪表板中,地图会根据使用 flexdashboard 通过下拉输入选择器选择的变量标签动态变化。

我认为解决方案应该是在 hc_tooltip() 中创建一个 if 语句,以在值 > 1 时应用不带小数的逗号格式,或者将该值乘以 100 并添加一个 %前缀如果值 < 1.

我曾尝试阅读 highcharter 文档以试图弄清楚这一点,但我的正式编程培训确实为零,并且一无所知 javascript 因此 highcharter 文档对我来说很难理解。似乎可以做到的一种方法是在 hc_tooltip() 中使用 JS 函数,例如 hc_tooltip(formatter = JS("function() {}). 我不知道如何在这样的函数中引用 {point.value} 的值。 我发现了一些似乎与我的问题相似的 Whosebug posts,但我不明白如何修改我的代码以使它们工作。一个 post 我一直在努力理解的是这个:

我试过在数据框中的适当值上使用 scales::percent() 和 scales::comma(),然后再将它们传递给地图(就像在创建 df 之后一样),但看起来hc_add_series_map() 不喜欢以这种方式传递变量。

请帮助我了解如何解决这个问题或提供一个我可以用来理解的解决方案。在我学习用 R 编写代码的短时间内,我认为这可能是我挣扎时间最长的事情,我现在感到非常沮丧,因为我无法弄清楚。

library(tidyverse) 
library(utils) 
library(stats) 
library(labelled)
library(highcharter)
library(shiny) 
library(expss)

x<- structure(list(state = structure(c("Alabama", "Alaska", "Arizona", 
                                       "Arkansas", "California", "Colorado", "Connecticut", "Delaware", 
                                       "District Of Columbia", "Florida", "Georgia", "Hawaii", "Idaho", 
                                       "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", 
                                       "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", 
                                       "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", 
                                       "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", 
                                       "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", 
                                       "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", 
                                       "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", 
                                       "Wyoming"), label = "State"), count = structure(c(88972, 18217, 
                                                                                         99224, 43942, 451964, 79864, 74454, 20558, 24895, 327488, 140264, 
                                                                                         28621, 26095, 204099, 127416, 59616, 60374, 72304, 62918, 27603, 
                                                                                         86983, 147895, 149864, 116927, 48100, 119469, 18994, 32954, 48781, 
                                                                                         24601, 137461, 29405, 382436, 143585, 15428, 229085, 49448, 68338, 
                                                                                         229429, 25817, 72222, 18926, 107276, 350382, 36801, 20696, 109693, 
                                                                                         108594, 34110, 105354, 8107), label = "Count"), pctState = structure(c(0.0174, 
                                                                                                                                                                0.0036, 0.0194, 0.0086, 0.0883, 0.0156, 0.0146, 0.004, 0.0049, 
                                                                                                                                                                0.064, 0.0274, 0.0056, 0.0051, 0.0399, 0.0249, 0.0117, 0.0118, 
                                                                                                                                                                0.0141, 0.0123, 0.0054, 0.017, 0.0289, 0.0293, 0.0229, 0.0094, 
                                                                                                                                                                0.0234, 0.0037, 0.0064, 0.0095, 0.0048, 0.0269, 0.0057, 0.0748, 
                                                                                                                                                                0.0281, 0.003, 0.0448, 0.0097, 0.0134, 0.0448, 0.005, 0.0141, 
                                                                                                                                                                0.0037, 0.021, 0.0685, 0.0072, 0.004, 0.0214, 0.0212, 0.0067, 
                                                                                                                                                                0.0206, 0.0016), label = "Percent")), row.names = c(NA, -51L), class = "data.frame")

y<- "Count". #change y to "Percent" to get the other value in the dataframe for display

get_map <- function(x, y){
  data("usgeojson")
 
  z<- look_for(x, y, details= FALSE, labels = TRUE,
               ignore.case = FALSE)
  a<- z$variable
  
  df<- x %>%
    select(all_of(a))
  
  metric1<- y
  value1<-  colnames(df)
 
  highchart() %>%
    hc_add_series_map(usgeojson, x,
                      name = metric1,
                      value = value1,
                      joinBy = c("woename", "state"))%>%
    hc_mapNavigation(enabled = T) %>%
    hc_tooltip(pointFormat = "{point.value}"
               ) %>%
    hc_colorAxis(min= min(df),
                 max= max(df),
                 startOnTick= FALSE,
                 endOnTick= FALSE)
}

get_map(x, y)

我终于明白了!上周花了很多时间,但现在可以了。该解决方案有两个部分。一部分是在输入函数以使用千位分隔符

格式化值之前,将 highcharter 的格式化说明添加到我的仪表板
lang<-getOption("highcharter.lang")
lang$thousandsSep<-","
options(highcharter.lang = lang)

第二部分是用一些 ifelse 语句重写我的函数,将数据框分成需要按百分比格式化的变量和不需要的变量。

get_map <- function(x, y){
  data("usgeojson")
  
  z<- look_for(x, y, details= FALSE, labels = TRUE,
               ignore.case = FALSE)
  a<- z$variable
  
  df<- x %>%
    select(all_of(a))
  
  decimals<-ifelse(mean(df[,1])>1,0,1)
  
  df[1]<-ifelse(mean(df[,1])>1,df[1],df[1]*100)    
  df[2]<-x[1]
  
  value1<-  colnames(df[1])
  highchart() %>%
    hc_add_series_map(usgeojson, df,
                      name = y,
                      value = value1,
                      joinBy = c("woename", "state"))%>%
    hc_mapNavigation(enabled = T) %>%
    hc_tooltip(valueDecimals= decimals,valueSuffix=ifelse(mean(df[,1])>100 | value1== "popratio","","%")
    ) %>% 
    hc_colorAxis(min= min(df[1]),
                 max= max(df[1]),
                 startOnTick= FALSE,
                 endOnTick= FALSE)
}

最终它实际上并不需要任何 JS 函数,尽管我想它仍然可以通过这种方式解决。很难找出 highcharter 设置并将它们转换为适用于 R 的语法。