【问题标题】:printing blanks instead of NA's when using formattable in R在 R 中使用 formattable 时打印空白而不是 NA
【发布时间】:2017-06-03 19:20:50
【问题描述】:

考虑示例 data.frame

df <- data.frame(
  id = 1:4,
  name = c("Bob", "Ashley", "James", "David"), 
  age = c(48, NA, 40, 28),
  test1_score = c(18.9, 19.5, NA, 12.9),
  stringsAsFactors = FALSE)

我正在使用 R 包 formattable 制作一个漂亮的表格。

library(formattable)
formattable(df, list(
age = color_tile("white", "orange"),
test1_score = color_bar("pink", 'proportion', 0.2)
))

过去是自动不打印 NA,而是打印空白。似乎这不再是默认设置,但我仍然想为 NA 打印一个空白。像这样替换 NA 有效:

df[is.na(df)]=''
formattable(df, list(
  age = color_tile("white", "orange"),
  test1_score = color_bar("pink", 'proportion', 0.2)
))

但是,如果我尝试格式化其中一列以强制它具有 2 个小数位,那么讨厌的 NA 会返回:

df$age = digits(df$age, digits=2)
formattable(df, list(
age = color_tile("white", "orange"),
test1_score = color_bar("pink", 'proportion', 0.2)
))

如果我再次删除 NA,NA 会消失,但小数位也会消失

df[is.na(df)] = ''
formattable(df, list(
age = color_tile("white", "orange"),
test1_score = color_bar("pink", 'proportion', 0.2)
))

我相信原因是数字将df$age 转换为formattable numeric 对象并创建NA,而df[is.na(df)] = ''df$age 转换为formattable character 对象:

> df$age = digits(df$age, digits=2)
> df$age
[1] 48.00  NA   40.00 28.00
> class(df$age)
[1] "formattable" "numeric"    
> df[is.na(df)] = ''
> df$age
[1] "48" "  " "40" "28"
> class(df$age)
[1] "formattable" "character" 

关于解决方案的任何想法?

最后我还想将它与过滤后的 data.frame 一起使用,我使用来自Filtering dataframes with formattable 的代码来确保在过滤 data.frame 时色标保持不变:

df$age = digits(df$age, digits=2)
  subset_df <- function(m) {
    formattable(df[m, ], list(
      age = x ~ color_tile("white", "orange")(df$age)[m],
      test1_score = x ~ color_bar("pink", 'proportion', 0.2)(df$test1_score)[m],
      test2_score = x ~ color_bar("pink", 'proportion', 0.2)(df$test2_score)[m]
    ))
  }

subset_df(1:3)

不过,问题似乎与此代码无关。

【问题讨论】:

    标签: r formattable


    【解决方案1】:

    您可以使用sprintf 函数将数字列格式化为具有所需小数位数的字符串。在下面的代码中,sprintfNA 转换为字符串"NA",然后我们将其转换为空字符串。

    # Function to convert numeric values to strings with a given number of 
    #  decimal places, and convert NA to empty string
    fnc = function(var, decimal.places) {
      var = sprintf(paste0("%1.",decimal.places,"f"), var)
      var[var=="NA"] = ""
      var
    }
    
    # Select the columns we want to reformat
    vars = c('age', 'test1_score')
    
    # Apply the function to the desired columns with the desired number of decimal places
    df[ , vars] = mapply(fnc, df[ ,vars], 2:3)
    
    formattable(df, list(
      age = color_tile("white", "orange"),
      test1_score = color_bar("pink", 'proportion', 0.2)
    ))
    

    【讨论】:

      【解决方案2】:

      另一个对我有用的解决方案是使用str_remove_all()。因为formattable 中的color_bar() 将HTML 输出作为字符生成,所以您只需删除字符串“NA”。

      请注意,如果您碰巧在其他任何地方有 NA,这可能会弄乱 HTML。 另外值得注意的是,我在 your_var 周围包裹了一个百分比函数。 这是我能想到的将数字转换为百分比并应用color_bar() 的最佳方法。代码如下:

      df %>%
          # First mutate w/color_bar()
          mutate(your_var= color_bar("green", na.rm=T)(percent(your_var, digits = 1))) %>% 
          # Second mutate
          mutate(your_var = str_remove_all(your_var, "NA"))
      

      第一次变异的输出

      <span style="display: inline-block; direction: rtl; border-radius: 4px; padding-right: 2px; background-color: #00a657">NA</span>
      

      第二次变异的输出

      <span style="display: inline-block; direction: rtl; border-radius: 4px; padding-right: 2px; background-color: #00a657"></span>
      

      另外,如果有人还没有看到这个:Awesome tables in HTML - Integration with formattable

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-21
        • 2018-06-28
        • 1970-01-01
        • 2013-10-31
        • 1970-01-01
        • 2012-09-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多