我正在 R 中工作,我有不同的数据帧,所有数据帧都具有定义为因子的不同/多个列。然后,我将这些数据帧可视化为 R Shiny 应用程序中的数据表。当我对类型因子的任何列进行排序时,排序是按字母顺序排列的,并且不考虑实际的因子值。因此,我尝试创建一个如下所示的函数,以便它检查输入数据帧是否具有因子列并自动修复其排序“问题”,以便它们不按字母顺序排序,而是使用实际因子值。 我在这里发现了一个有趣的问题使用 DT 包在数据表中排序因子但是,这仅适用于一列。 您知道如何解决我下面的尝试吗?
library(shiny)
library(DT)
# Define a function to create a datatable with factor columns sorted by factor values
create_datatable <- function(df) {
# Identify the factor columns
factor_cols <- sapply(df, is.factor)
# Create a list of column definitions for factor columns
factor_defs <- lapply(which(factor_cols), function(i) {
list(targets = i-1, type = 'natural')
})
# Create the datatable with column definitions
DT::datatable(df,
options = list(orderClasses = TRUE),
rownames = FALSE,
class = 'cell-border stripe',
columnDefs = factor_defs
)
}
# Define a sample dataframe with factor columns
df <- data.frame(
x = factor(c("A", "B", "C")),
y = factor(c("Low", "High", "Medium")),
z = factor(c("Yes", "No", "Maybe")),
a = c(1, 2, 3),
b = c(4, 5, 6)
)
# Define the UI
ui <- fluidPage(
DT::dataTableOutput("mytable")
)
# Define the server
server <- function(input, output) {
output$mytable <- DT::renderDataTable({
# Create the datatable with factor columns sorted by factor values
create_datatable(df)
})
}
# Run the app
shinyApp(ui, server)
columnDefs
,然后将其示例转换为 R 结构,我们可以看到它正在寻找什么类型的嵌套列表:
str(jsonlite::fromJSON('[
{ "targets": [0, 1], "visible": true},
{ "targets": "_all", "visible": false }
]'))
# 'data.frame': 2 obs. of 2 variables:
# $ targets:List of 2
# ..$ : int 0 1
# ..$ : chr "_all"
# $ visible: logi TRUE FALSE
而你的清单是
str(factor_defs)
# List of 3
# $ x:List of 2
# ..$ targets: num 0
# ..$ type : chr "natural"
# $ y:List of 2
# ..$ targets: num 1
# ..$ type : chr "natural"
# $ z:List of 2
# ..$ targets: num 2
# ..$ type : chr "natural"
此外,它需要将所有这些都放在另一个
list
中,然后在 options=
列表中应用。
我们可以使用此版本代替您的
lapply
版本来修复它:
create_datatable <- function(df) {
# Identify the factor columns
factor_cols <- sapply(df, is.factor)
# Create a list of column definitions for factor columns
factor_defs <- list(list(
targets = which(factor_cols),
type = rep("natural", sum(factor_cols))
))
# Create the datatable with column definitions
DT::datatable(df,
options = list(orderClasses = TRUE, columnDefs = factor_defs),
rownames = FALSE,
class = 'cell-border stripe'
)
}