【问题标题】:Could not find function within ShinyApp while using source使用源代码时在 ShinyApp 中找不到函数
【发布时间】:2020-09-12 07:10:17
【问题描述】:

我有一个闪亮的应用程序,其中包含两个文件:app.R 和 functions.R

app.R:

# Setup ----
pacman::p_load(shiny, tidyverse, shinydashboard, lubridate, scales, DT)
source('functions.R', local = T)


# UI ----
header <- dashboardHeader(title = 'Velocity Spend & Return Calculator')
HTML("Adjust spend column for calculations")

sidebar <- dashboardSidebar(
  menuItem("dh", tabName = "dh", icon = icon("dashboard"))
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dh",
            h2("DH Estimator"),
            HTML("Adjust spend column for calculations"),
            DT::DTOutput('example_ui_dh')
            
    )
  )
)


ui <- dashboardPage(header, sidebar, body)


# Server ----
server <- function(input, output) {
  
  # Initial budgets, eventually set to come from dropdowns or user input
  budgets <- list(
    '2020.4' = 1000000,
    '2021.1' = 1000000,
    '2021.2' = 1000000,
    '2021.3' = 1000000,
    '2021.4' = 1000000
  )
  
  dh_proxy = DT::dataTableProxy('example_ui_dh')
  
  # eventually use distinct budgets for each, just demo right now
  output$example_ui_dh <- render_dt(budgets)
  
  # eventually make this a function
  # pass for now and just copy paste for demo
  # adding observeEvent to a function is not straightforwards
  
  # dh
  observeEvent(input$example_ui_dh_cell_edit, {
    info = input$example_ui_dh_cell_edit
    str(info)
    i = info$row
    j = info$col
    v = info$value
    budgets[[i]] <<- v %>% as.numeric()
    replaceData(dh_proxy, create_sample_df(budgets), resetPaging = FALSE)
  })
  
}
shinyApp(ui, server)

和函数。R

# generates an example df based on inputed budgets
create_sample_df <- function(budgets) {
    data.frame(cohort = seq('2020-10-01' %>% ymd, '2021-12-31' %>% ymd, by = '1 days')) %>% 
    mutate(Quarter = quarter(cohort, with_year = T)) %>% 
    add_count(Quarter) %>% 
    mutate(DailyBudget = budgets[Quarter %>% as.character] %>% unlist / n) %>% 
    group_by(Quarter) %>% 
    mutate(Revenue = DailyBudget + rnorm(n(), mean = 0, sd = DailyBudget / 5)) %>% 
    summarise(Spend = sum(DailyBudget),
              Revenue = sum(Revenue),
              .groups = 'drop') %>% 
    mutate(Profit = dollar(Revenue - Spend),
           Payback = percent(Revenue / Spend),
           Spend = dollar(Spend),
           Revenue = dollar(Revenue)) %>% 
    mutate(Quarter = as.character(Quarter)) # do this last keep ordering of quarters
}



# render DT
render_dt <- function(budgets, ...) {
  DT::renderDT(create_sample_df(budgets), editable = 'cell', server = T, 
               list(target = 'column', disable = list(columns = c(0,2,3,4))))
}

如果我打开项目目录并运行,我会收到一条错误消息:

错误:找不到函数“create_sample_df”

如果在运行应用程序之前,我在控制台中手动运行 functions.R 中的函数,那么应用程序确实会加载。

实际上,我必须在控制台中运行 functions.R 中的代码,然后运行变量预算。只有当我做这两件事时,我的应用程序才会运行。这使我无法发布应用程序。

我已经尝试在服务器和 observEvent 中获取函数文件,更多的是出于绝望的行为。我在创建budgets 变量时做了同样的事情。

当我将函数和预算变量作为变量加载到环境中时,应用程序运行良好,但在第一次运行时就不行。

如何构建我的应用程序以使其在首次加载时运行?

请注意,当应用加载时,您需要单击“dh”选项卡才能看到结果。

[编辑]

根据 Akrun 的评论更新代码,使用 myenv:

# Setup ----
pacman::p_load(shiny, tidyverse, shinydashboard, lubridate, scales, DT)
myenv <- new.env()
source('functions.R', local  = myenv)


# UI ----
header <- dashboardHeader(title = 'Velocity Spend & Return Calculator')
HTML("Adjust spend column for calculations")

sidebar <- dashboardSidebar(
  menuItem("dh", tabName = "dh", icon = icon("dashboard"))
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dh",
            h2("DH Estimator"),
            HTML("Adjust spend column for calculations"),
            DT::DTOutput('example_ui_dh')
            
    )
  )
)


ui <- dashboardPage(header, sidebar, body)


# Server ----
server <- function(input, output) {
  
  # Initial budgets, eventually set to come from dropdowns or user input
  budgets <- list(
    '2020.4' = 1000000,
    '2021.1' = 1000000,
    '2021.2' = 1000000,
    '2021.3' = 1000000,
    '2021.4' = 1000000
  )
  
  dh_proxy = DT::dataTableProxy('example_ui_dh')
  
  # eventually use distinct budgets for each, just demo right now
  output$example_ui_dh <- myenv$render_dt(budgets)
  
  # dh
  observeEvent(input$example_ui_dh_cell_edit, {
    info = input$example_ui_dh_cell_edit
    str(info)
    i = info$row
    j = info$col
    v = info$value
    budgets[[i]] <<- v %>% as.numeric()
    replaceData(dh_proxy, myenv$create_sample_df(budgets), resetPaging = FALSE)
  })
  
}
shinyApp(ui, server)

会话信息:

sessionInfo()
R version 3.6.0 (2019-04-26)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: Amazon Linux 2

Matrix products: default
BLAS/LAPACK: /usr/lib64/R/lib/libRblas.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C               LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] DT_0.14              scales_1.1.0         lubridate_1.7.4      shinydashboard_0.7.1 forcats_0.4.0        stringr_1.4.0        dplyr_1.0.2          purrr_0.3.4         
 [9] readr_1.3.1          tidyr_1.0.0          tibble_3.0.1         ggplot2_3.3.2        tidyverse_1.3.0      shiny_1.4.0         

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6      lattice_0.20-38   assertthat_0.2.1  digest_0.6.25     packrat_0.5.0     mime_0.9          R6_2.4.1          cellranger_1.1.0  backports_1.1.8  
[10] reprex_0.3.0      evaluate_0.14     httr_1.4.1        pillar_1.4.4      rlang_0.4.7       readxl_1.3.1      rstudioapi_0.11   rmarkdown_2.1     htmlwidgets_1.5.1
[19] munsell_0.5.0     broom_0.5.3       compiler_3.6.0    httpuv_1.5.2      modelr_0.1.5      xfun_0.15         pkgconfig_2.0.3   htmltools_0.5.0   tidyselect_1.1.0 
[28] fansi_0.4.1       withr_2.2.0       crayon_1.3.4      dbplyr_1.4.2      later_1.1.0.1     grid_3.6.0        nlme_3.1-143      jsonlite_1.7.0    xtable_1.8-4     
[37] gtable_0.3.0      lifecycle_0.2.0   DBI_1.1.0         pacman_0.5.1      magrittr_1.5      cli_2.0.2         stringi_1.4.6     fs_1.4.2          promises_1.1.1   
[46] xml2_1.3.2        ellipsis_0.3.1    generics_0.0.2    vctrs_0.3.4       tools_3.6.0       glue_1.3.2        crosstalk_1.1.0.1 hms_0.5.3         rsconnect_0.8.16 
[55] fastmap_1.0.1     yaml_2.2.1        colorspace_1.4-1  rvest_0.3.5       knitr_1.29        haven_2.2.0      

【问题讨论】:

  • 没有?不确定那是什么?我使用 T 作为 TRUE 的 rstudio 简写
  • 只需将文件functions.R重命名为global.R即可。那么你就不需要来源了。
  • 好的,将简写 T 更改为 TRUE
  • 基于this 它应该可以工作
  • 是的,看起来确实是同一个问题,但即使在我对 source 的调用中添加 local = TRUE 也会导致找不到函数的相同错误

标签: r shiny


【解决方案1】:

新环境下功能正常

-输出

-会话

sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] DT_0.14              lubridate_1.7.9      shinydashboard_0.7.1 sjlabelled_1.1.6     scales_1.1.1         labelled_2.6.0       haven_2.3.1         
 [8] tidyr_1.1.0          ggplot2_3.3.2        dplyr_1.0.1          questionr_0.7.2      shiny_1.5.0         

loaded via a namespace (and not attached):
 [1] tidyselect_1.1.0  purrr_0.3.4       snakecase_0.11.0  colorspace_1.4-1  vctrs_0.3.2       generics_0.0.2    miniUI_0.1.1.1    htmltools_0.5.0  
 [9] yaml_2.2.1        rlang_0.4.7       later_1.1.0.1     pillar_1.4.6      glue_1.4.1        withr_2.2.0       lifecycle_0.2.0   munsell_0.5.0    
[17] gtable_0.3.0      htmlwidgets_1.5.1 labeling_0.3      forcats_0.5.0     fastmap_1.0.1     httpuv_1.5.4      crosstalk_1.1.0.1 curl_4.3         
[25] fansi_0.4.1       highr_0.8         Rcpp_1.0.5        xtable_1.8-4      readr_1.3.1       promises_1.1.1    jsonlite_1.7.0    mime_0.9         
[33] farver_2.0.3      hms_0.5.3         digest_0.6.25     stringi_1.4.6     insight_0.9.0     grid_4.0.2        cli_2.0.2         tools_4.0.2      
[41] magrittr_1.5      tibble_3.0.3      pacman_0.5.1      crayon_1.3.4      pkgconfig_2.0.3   ellipsis_0.3.1    assertthat_0.2.1  rstudioapi_0.11  
[49] R6_2.4.1          compiler_4.0.2   

-代码

pacman::p_load(shiny, dplyr, shinydashboard, lubridate, scales, DT)

myenv <- new.env()
source(file.path(getwd(), 'Downloads/functions_new.R'), local  = myenv)


# UI ----
header <- dashboardHeader(title = 'Velocity Spend & Return Calculator')
HTML("Adjust spend column for calculations")

sidebar <- dashboardSidebar(
  menuItem("dh", tabName = "dh", icon = icon("dashboard"))
)

body <- dashboardBody(
  tabItems(
    tabItem(tabName = "dh",
            h2("DH Estimator"),
            HTML("Adjust spend column for calculations"),
            DT::DTOutput('example_ui_dh')
            
    )
  )
)


ui <- dashboardPage(header, sidebar, body)


# Server ----
server <- function(input, output) {
  
  # Initial budgets, eventually set to come from dropdowns or user input
  budgets <- list(
    '2020.4' = 1000000,
    '2021.1' = 1000000,
    '2021.2' = 1000000,
    '2021.3' = 1000000,
    '2021.4' = 1000000
  )
  
  dh_proxy = DT::dataTableProxy('example_ui_dh')
  
  # eventually use distinct budgets for each, just demo right now
  output$example_ui_dh <- myenv$render_dt(budgets)
  
  print(budgets)
  # dh
  observeEvent(input$example_ui_dh_cell_edit, {
    info = input$example_ui_dh_cell_edit
    str(info)
    i = info$row
    j = info$col
    v = info$value
    budgets[[i]] <<- v %>% as.numeric()
    replaceData(dh_proxy, myenv$create_sample_df(budgets), resetPaging = FALSE)
  })
  
}
shinyApp(ui, server)

【讨论】:

  • @DougFir 从您的会话信息中,我发现 shiny 为 1.4.0,我有 1.5.0
  • 更新了所有的包,闪亮的现在是 1.5... 问题仍然存在
  • @DougFir 对不起,我希望我能得到一个答案,会做研究,如果我发现了什么,会更新你
  • 嗯,很有趣。我以前从未这样做过,但会在星期一试一试。感谢您的建议,将在此处更新内容...
  • 我通过编辑我的函数解决了这个问题。在我原来的functions.R上面我的函数render_dt又调用另一个函数create_sample_df。这似乎是问题所在。因此,我将定义更改为render_dt = function(data, editable = 'cell', server = TRUE, ...) { renderDT(data, selection = 'none', server = server, editable = editable, ...) },然后像这样称呼它render_dt(create_sample_df(budgets), rownames= FALSE, list(target = 'column', ...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 2012-12-17
  • 2021-09-28
  • 2014-04-07
相关资源
最近更新 更多