代码
library(DT)
datatable(head(iris, 10))
不止BI
2024年4月6日
DT包是一个在R语言中非常有用的数据处理工具。它提供了DataTables JavaScript库在R中的接口,使得R中的对象(如矩阵或数据框)可以在HTML页面上以表格形式显示,并且具备数据筛选、分页、排序等功能 ## 默认样式
通过传入翻译的json可以修改控件语言为中文
默认情况下列宽自适应
在DT包中,dom参数用于控制一些元素在表格周围的位置。具体而言,它决定了哪些控件(如分页、搜索框、表格信息等)显示在表格的哪个位置。
l:Length changing,用于改变每页显示多少条数据的控件。
f:Filtering input,即时搜索框控件。
t:The Table,表格本身。
i:Information,表格相关信息控件。
p:Pagination,分页控件。
r:Processing,加载等待显示信息。
下方代码设置仅显示表格和分页控件,并且分页控件位于表格的上方
[1] "toDateString" "toISOString" "toLocaleDateString"
[4] "toLocaleString" "toLocaleTimeString" "toString"
[7] "toTimeString" "toUTCString"
library(RColorBrewer)
datatable(iris[sample(1:150, 30), ]) %>%
formatStyle("Sepal.Length", fontWeight = styleInterval(5, c("normal", "bold"))) %>%
formatStyle(
"Sepal.Width",
backgroundColor = styleInterval(quantile(iris$Sepal.Width, probs = c(0.05, 0.95)), brewer.pal(3, "Greens"))
) %>%
formatStyle(
"Petal.Width",
color = styleInterval(c(1, 2), c("black", "blue", "red"))
) %>%
formatStyle(
"Petal.Length",
background = styleColorBar(iris$Petal.Length, "steelblue"),
backgroundSize = "100% 90%",
backgroundRepeat = "no-repeat",
backgroundPosition = "center"
) %>%
formatStyle(
"Species",
# transform = 'rotateX(45deg) rotateY(20deg) rotateZ(30deg)',
backgroundColor = styleEqual(
unique(iris$Species), brewer.pal(3, "Accent")
)
)
datatable(iris[sample(1:150, 30), ], options = list(columnDefs = list(
list(targets = "_all", className = "dt-head-center")
))) |>
# 为第1:4列设定文本对齐方式为居中
formatStyle(columns = c(1:4), textAlign = "center") |>
# 目标为行,按照第5列('type2'列)的数据值,设定不同行应用不同的文本对齐方式
formatStyle(
columns = 5,
target = "row",
textAlign = styleEqual(
levels = c("setosa", "virginica", "versicolor"),
values = c("left", "right", "center")
)
)
datatable(head(mtcars)) |>
# 设定单元格的边框样式为宽度1px、虚线、黑色
formatStyle(columns = 1, "border" = "1px dashed black") |>
# 设定单元格的下边框样式为宽度1px、实线、黑色
formatStyle(columns = 2, "border-bottom" = "1px solid black") |>
# 设定单元格的上边框样式为宽度1px、点线、黑色
formatStyle(columns = 3, "border-top" = "1px dotted black") |>
# 设定单元格的左边框样式为宽度2px、实线、红色
formatStyle(columns = 4, "border-left" = "2px solid red") |>
# 设定单元格的右边框为宽度1px、实线、黑色
formatStyle(columns = c(5, 6), "border-right" = "1px solid black")
鼠标悬浮单元格时,右下角会出现蓝色方块,通过拖动蓝色方块实现自动填充
通过自定义container
来实现列分组的功能,如下示例中rowspan = 2
代表占两行,colspan = 2
代表占两列
# a custom table container
library(htmltools)
sketch <- htmltools::withTags(table(
class = 'display',
style = 'border-collapse: collapse;', # 添加边框合并,使网格线更清晰
thead(
tr(
th(rowspan = 2, style = 'border: 1px solid #D3D3D3; text-align: center;', 'Species'),
th(colspan = 2, style = 'border: 1px solid #D3D3D3; text-align: center;', 'Sepal'),
th(colspan = 2, style = 'border: 1px solid #D3D3D3; text-align: center;', 'Petal')
),
tr(
lapply(rep(c('Length', 'Width'), 2), function(text) {
th(style = 'border: 1px solid #D3D3D3; text-align: center;', text)
})
)
)
))
datatable(iris[1:20, c(5, 1:4)], container = sketch, rownames = FALSE,class = 'cell-border stripe')
通过JS引入HTML代码,<a class="自定义 CSS 类名" href="超链接地址" title="悬停提示语">超链接显示名</a>
hrefdata <- data.frame(Id = 1:5, Letters = LETTERS[1:5], Href = rep("https://notjustbi.netlify.app/", 5))
# 由于超链接地址在表中第3列,所以列渲染时写row[3]
datatable(hrefdata,
options = list(columnDefs = list(
list(
targets = 2,
render = JS(
"function(data, type, row, meta) {
return '<a href=' + row[3] + ' title=' +row[3] + '>' + data + '</a>'
}"
)
), list(targets = 3, visible = FALSE) # 隐藏 hrefvalue 列
))
)
imgdata <- data.frame(Id = 1:5, Letters = LETTERS[1:5], imgvalue = rep("favicon", 5))
# 由于图片名字在表中第3列,所以列渲染时写row[3]
datatable(imgdata,
options = list(columnDefs = list(
list(
targets = 1,
render = JS("function(data, type, row, meta) {
return '<img width=30% src=\"' + row[3] + '.png\"/> '
}")
), list(targets = 3, visible = FALSE) # 隐藏 imgvalue 列
))
)
通过sparkline
包添加
library(sparkline)
library(dplyr)
data <- data.frame(value = rnorm(12))
spark_html <- function(...) {
as.character(htmltools::as.tags(sparkline(..., height = 100, width = 100)))
}
data <- data %>% summarise(
"面积图" = spark_html(value, type = "line"),
"柱状图" = spark_html(value, type = "bar"),
"折线图" = spark_html(
value,
type = "line",
lineColor = "red", # 折线的颜色
fillColor = FALSE # 不展示折线下的面积
),
"柱状图2" = spark_html(value, type = "bar", barColor = "green"),
"箱图" = spark_html(value, type = "box")
)
datatable(data, escape = FALSE, options = list(fnDrawCallback = htmlwidgets::JS("function(){
HTMLWidgets.staticRender();
}"))) %>%
spk_add_deps()
df <- data.frame(group = rep(c("a", "b"), 5), value = runif(10)) %>%
group_by(group) %>%
summarise(piechart = as.character(htmltools::as.tags(
sparkline(
value,
type = "pie", # 饼图
sliceColors = brewer.pal(5, "Set2"), # 指定饼图中各个扇形的颜色。
offset = 90, # 指定饼图的旋转角度
width = 50, # 指定迷你图的宽度
height = 50 # 指定迷你图的高度
)
)))
datatable(df,
escape = FALSE,
options = list(
dom = "tip",
# 每次分页重新渲染,不加这个的话只有第一页有图
drawCallback = JS("function(s) { HTMLWidgets.staticRender(); }")
)
) |> spk_add_deps()
df <- data.frame(group = rep(c("a", "b"), 5), value1 = runif(10), value2 = runif(10)) %>%
group_by(group) %>%
summarise("两条折线" = as.character(htmltools::as.tags(spk_composite(
sparkline(
value1,
type = "line",
fillColor = FALSE,
lineColor = "red", # 指定折线的颜色
width = 200,
height = 100
),
sparkline(
value2,
type = "line",
fillColor = FALSE,
lineColor = "green",
width = 200,
height = 100
)
))))
datatable(df, escape = FALSE, options = list(fnDrawCallback = htmlwidgets::JS("function(){
HTMLWidgets.staticRender();
}"))) |> spk_add_deps()
library(crosstalk)
data <- data.frame(value1 = rnorm(10), value2 = rnorm(10), type = rep(c("a", "b"), 5))
shared_data <- SharedData$new(data)
bscols(list(
plotly::plot_ly(
data = shared_data,
type = "scatter",
mode = "markers+text",
x = ~value1,
y = ~value2,
color = ~type
),
DT::datatable(
shared_data,
width = "100%",
rownames = FALSE,
filter = "bottom",
# 允许使用正则,[A|B]表示多选A或B
options = list(search = list(regex = TRUE))
)
))
formattable
包生成的静态表格可以通过as.datatable()
转为DT表格
library(formattable)
products <- data.frame(
id = 1:5,
price = c(10, 15, 12, 8, 9),
rating = c(5, 4, 4, 3, 4),
market_share = percent(c(0.1, 0.12, 0.05, 0.03, 0.14)),
revenue = accounting(c(55000, 36400, 12000, -25000, 98100)),
profit = accounting(c(25300, 11500, -8200, -46000, 65000))
)
sign_formatter <- formatter("span",
style = x ~ style(color = ifelse(x > 0, "green",
ifelse(x < 0, "red", "black")
))
)
formattable(products, list(
price = color_tile("transparent", "lightpink"),
rating = color_bar("lightgreen"),
market_share = color_bar("lightblue"),
revenue = sign_formatter,
profit = sign_formatter
)) %>% as.datatable()