在使用R中的formattable时,打印空白而不是NA。

9
考虑以下数据框示例。
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)
))

enter image description here

然而,如果我尝试对其中一列进行格式化,以强制其保留两位小数,那么这些讨厌的NA值会重新出现:
df$age = digits(df$age, digits=2)
formattable(df, list(
age = color_tile("white", "orange"),
test1_score = color_bar("pink", 'proportion', 0.2)
))

enter image description here

如果我再次去除NA,那么NA就会消失,但小数位也会跟着消失。
df[is.na(df)] = ''
formattable(df, list(
age = color_tile("white", "orange"),
test1_score = color_bar("pink", 'proportion', 0.2)
))

enter image description here

我认为原因是数字将 df$age 转换为一个 可格式化的数字 对象并创建了 NA,而 df[is.na(df)] = ''df$age 转换为一个 可格式化的字符 对象:
> 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" 

有关解决方案的任何想法吗?

最终,我还想将其与过滤后的数据框一起使用,我使用 使用formattable过滤数据框中的代码来确保在过滤数据框时颜色比例尺保持不变:

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)

enter image description here

这个问题似乎与这段代码无关。
2个回答

7
您可以使用 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)
))

enter image description here


0
另一个对我有效的解决方案是使用str_remove_all()。因为formattable中的color_bar()将HTML输出作为字符生成,所以你可以直接移除字符串"NA"。 请注意,这可能会破坏HTML,如果你偶然在其他地方有NA的话。 还值得注意的是,我在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>

另外,如果有人还没有看到这个:HTML中的精美表格 - 与formattable集成


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接