在 R 中使用 formattable 时打印空白而不是 NA
printing blanks instead of NA's when using formattable in R
考虑示例 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 包格式table 制作一个漂亮的table。
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 return:
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)
))
我认为原因是 digits 将 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 一起使用,我使用 中的代码来确保在过滤 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)
问题似乎不在于此代码。
您可以使用 sprintf
函数将数字列格式化为具有所需小数位数的字符串。在下面的代码中,sprintf
将 NA
转换为字符串 "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)
))
另一个对我有用的解决方案是使用 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
考虑示例 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 包格式table 制作一个漂亮的table。
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 return:
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)
))
我认为原因是 digits 将 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 一起使用,我使用
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)
问题似乎不在于此代码。
您可以使用 sprintf
函数将数字列格式化为具有所需小数位数的字符串。在下面的代码中,sprintf
将 NA
转换为字符串 "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)
))
另一个对我有用的解决方案是使用 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