为什么 as.factor() 函数在 Shiny 反应式表达式中不起作用,但在 Shiny 之外的 R 基础中工作正常?

Why does the as.factor() function not work in a Shiny reactive express, but works fine outside of Shiny in base R?

提问人:Village.Idyot 提问时间:3/30/2023 更新时间:3/30/2023 访问量:47

问:

在底部发布的示例代码中,当在 Shiny 响应式中运行代码时,我得到了与在 Shiny 外部运行代码时函数不同的结果。我做错了什么?我想我在 Shiny 课程中错过了一些基本的东西。as.factor()

数据是“生存”包中的数据。在我的示例代码中,对象是在 Shiny 外部生成的,而对象是在 Shiny 内部作为响应式生成的。对象是正确的,object_2不正确,如下图所示。两者应该相同。下面的示例假设在 中选择了“”作为组变量,并且它应该是一个因子类。lunglung_1lung_2lung_1lung_1lung_2selectInput()

enter image description here

法典:

library(shiny)
library(survival)

lung_1 <- lung %>% mutate(group = as.factor(sex))

ui <- fluidPage(
  selectInput(
    "varCon", 
    "Grouping variable:",
     c("None" = 1,
       "sex" = "sex",
       "ph.ecog" = "ph.ecog"
     )
  )
)

server <- function(input, output, session) {
  lung_2 <- reactive({lung %>% mutate(group = as.factor(input$varCon))})
  
  # throw reactive DF into global environment to peek at what's going on...
  oe <- reactive({lung_2()})
  observeEvent(oe(),{lung_2.R <<- oe()})
  
}

shinyApp(ui, server)
Shiny -反应性 R 因子

评论


答:

1赞 szmple 3/30/2023 #1

您面临的问题是由于 Shiny 外部和内部代码执行之间的时间差异。

当您在 Shiny 外部运行代码时,as.factor() 函数会在 mutate() 函数之后立即执行。这意味着生成的组列具有类因子。

但是,当您在 Shiny 中运行代码时,as.factor() 函数仅在触发反应式表达式时执行。这意味着在触发反应式表达式并执行 as.factor() 函数之前,group 列是类字符的。

若要解决此问题,可以将组列转换为反应式表达式中的因子,而不是使用 mutate()。

 library(shiny)
library(survival)

lung_1 <- lung %>% mutate(group = as.factor(sex))

ui <- fluidPage(
  selectInput(
    "varCon", 
    "Grouping variable:",
     c("None" = 1,
       "sex" = "sex",
       "ph.ecog" = "ph.ecog"
     )
  )
)

server <- function(input, output, session) {
  lung_2 <- reactive({
    data <- lung
    if(input$varCon != 1) {
      data$group <- data[[input$varCon]]
    } else {
      data$group <- NA_character_
    }
    data$group <- as.factor(data$group)
    return(data)
  })
  
  # throw reactive DF into global environment to peek at what's going on...
  oe <- reactive({lung_2()})
  observeEvent(oe(),{lung_2.R <<- oe()})
  
}

shinyApp(ui, server)