gpt4 book ai didi

r - 使用 rhandsontable 在不同格式的响应式(Reactive)数据集之间切换

转载 作者:行者123 更新时间:2023-12-04 15:39:32 26 4
gpt4 key购买 nike

在这个很好的问题中:Shiny: Switching reactive datasets with Rhandsontable and external parameters数据帧和 rhandsontable 输出具有相同的结构。

我正在尝试解决类似的问题,但使用的数据集结构不同,并且数据集构建在嵌套列表中。考虑这个带有两个输入选择器的例子:

List and list element input selectors

根据输入选择器的不同,可以生成四种可能的表。他们是:

表 1(列表 1,“第一”):

First table

表 2(列表 1,“第二个”):

Second table

表 3(列表 2,“第三个”):

Third table

表4(列表2,“第四”):

Fourth table

每个表都通过 renderRHandsontable 元素出现在同一位置。我认为我的问题在于更新reactiveValue“值” - 你如何更新列表的元素而不是任何其他元素?这是一个显示正确的最小示例,但您无法更改任何元素(我正在尝试解决的问题)。

require(rhandsontable)
require(shiny)

# Create some fake lists
list_1 <- list()
list_2 <- list()
list_1[['first']] <- data.frame(matrix(1:4,ncol=4))
list_1[['second']] <- data.frame(matrix(1:2,ncol=2),bool=factor('a1',levels=c('a1','a2','a3')))
list_2[['third']] <- data.frame(matrix(7:9,ncol=3))
list_2[['fourth']] <- data.frame(matrix(10:11,ncol=2),bool=factor('b1',levels=c('b1','b2')))

ui <- fluidPage(sidebarLayout(sidebarPanel(
selectInput(
'list_selector', 'Select list:',
choices = c('list_1', 'list_2')
),
uiOutput("second_selectorUI")
),
mainPanel(rHandsontableOutput("out"))))

server <- function(input, output) {

values = reactiveValues()
values[["list_1"]] <- list_1
values[["list_2"]] <- list_2

# Feed user input back to the list
observe({
if (!is.null(input$out)) {
temp <- hot_to_r(input$out)
if (isolate(input$list_selector) %in% c('first','third')){
values[[isolate(input$list_selector)]][[isolate(input$list_selector)]] <- temp$values #Returns to wide format
} else {
values[[isolate(input$list_selector)]][[isolate(input$list_selector)]] <- temp
}
}
})

# Why isn't values[["list_1"]][[input$second_list_selector]] allowed?
list <- reactive({
if (input$list_selector == "list_1") {
values[["list_1"]]
} else if (input$list_selector == "list_2"){
values[["list_2"]]
}
})

output$second_selectorUI <- renderUI({
if (input$list_selector == 'list_1'){
selectInput(inputId = "second_list_selector", label="Select element 1",
choices = c('first', 'second'))
} else if (input$list_selector == 'list_2'){
selectInput(inputId = "second_list_selector", label="Select element 2",
choices = c('third', 'fourth'))
}
})

output$out <- renderRHandsontable({
if (!is.null(list()) && !is.null(input$second_list_selector)){
if (input$second_list_selector %in% c('first','third')){
df <- list()[[input$second_list_selector]]
df <- data.frame(values=as.numeric(df)) #Turns into long format
rhandsontable(df, stretchH = "all", rowHeaderWidth = 300, width=600)
} else if (input$second_list_selector %in% c('second','fourth')){
df <- list()[[input$second_list_selector]]
rhandsontable(df, stretchH = "all", rowHeaderWidth = 50, height = 300,width=600) %>%
hot_col("bool", allowInvalid = FALSE)
}
}
})
}

shinyApp(ui = ui, server = server)

最佳答案

这是一种方法:

ui <- fluidPage(
sidebarLayout(
sidebarPanel(
selectInput("sel_1", label = "Select list:",
choices = c("list_1", "list_2")),
selectInput("sel_2", label = "Select element 1",
choices = names(list_1))
),
mainPanel(
rHandsontableOutput("hot")
)
)
)

server <- function(input, output, session) {

list_1$first <- data.frame(values = as.numeric(list_1$first))
list_2$third <- data.frame(values = as.numeric(list_2$third))

values <- reactiveValues(list_1 = list_1, list_2 = list_2)

observe({
x <- input$sel_1
label <- paste("Select element", substr(x, nchar(x) - 1, nchar(x)))
updateSelectInput(session, "sel_2", label,
choices = names(values[[x]]))
})

# Key part: storing back the data in `values` every time there is a change
observe({
if (!is.null(input$hot) && !is.null(input$hot$changes$changes))
values[[isolate(input$sel_1)]][[isolate(input$sel_2)]] <- hot_to_r(input$hot)
})

output$hot <- renderRHandsontable({
df <- values[[input$sel_1]][[input$sel_2]]
if (is.null(df)) return(NULL)
if (input$sel_2 %in% c("first", "third")) {
rhandsontable(df, stretchH = "all", rowHeaderWidth = 300, width = 600)
} else {
rhandsontable(df, stretchH = "all", rowHeaderWidth = 50, height = 300, width = 600) %>%
hot_col("bool", allowInvalid = FALSE)
}
})

}

不过要小心这个答案,因为在我写它的时候,我仍然偶尔会看到奇怪的不可重现的错误,比如错误的表被覆盖,我发现在 rhandsontable 的上下文中很难控制 react 性。 .

关于r - 使用 rhandsontable 在不同格式的响应式(Reactive)数据集之间切换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49981955/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com