printing blanks instead of NA's when using formattable in R

自闭症网瘾萝莉.ら 提交于 2020-06-10 03:40:42

问题


Consider the example 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)

I'm using the R package formattable to make a pretty table.

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

It used to be that NA's were automatically not printed, and a blank was printed instead. It seems like this is no longer the default, but I would still like to print a blank for the NA. Replacing NA like this works:

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

However if I try to format one of the columns to force it to have 2 decimal places, the pesky NA's return:

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

If I remove the NA again, the NA goes away, but so do the decimal places

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

I believe the reason is that digits converts df$age to a formattable numeric object and creates the NA, and df[is.na(df)] = '' converts df$age to a formattable character object:

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

Any ideas on a solution?

Ultimately I'd also like to use this with a filtered data.frame, where I use the code from Filtering dataframes with formattable to ensure that the color scale stays the same when filtering the 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)

The problem doesn't seem to be with this code though.


回答1:


You could use the sprintf function to format the numeric columns as strings with the desired number of decimal places. In the code below, sprintf converts NA to the string "NA", which we then convert to an empty string.

# 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:


Another solution which worked for me was using str_remove_all(). Because color_bar() in formattable produces HTML output as a character, you can just remove the string "NA".

Note that this has the potential to mess up the HTML if you happened to have NA anywhere else. Also worth noting is that I wrap a percent function around your_var. This was the best way I could come up with to convert my numeric to percent and apply color_bar(). The code is below:

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

Output from First mutate

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

Output from Second mutate

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

Also, in case anyone hasn't seen this yet: Awesome tables in HTML - Integration with formattable



来源:https://stackoverflow.com/questions/44347734/printing-blanks-instead-of-nas-when-using-formattable-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!