【问题标题】:R Shiny: User defined function works well in regular R code but fails inside a shiny functionR Shiny:用户定义的函数在常规 R 代码中运行良好,但在闪亮函数中失败
【发布时间】:2018-03-30 05:50:11
【问题描述】:

我对 Shiny 很陌生,我正在尝试传递一个函数,该函数在数据框中创建老化括号,我在 Shiny 外部测试过这个函数到一个闪亮的应用程序中。

下面是Shiny外面的代码:

# Regular R Code
Aging <- function(data, Transaction.Date){
 if(missing(Transaction.Date)) stop("You forgot to specify Transaction Date")
 Transaction.Date <- deparse(substitute(Transaction.Date))
 data$year <- year(data[,Transaction.Date])
 data$Age <- car::recode(year(data[,Transaction.Date]), "year(Report.Date) = year(Report.Date); year(Report.Date)-1 = year(Report.Date)-1; else = paste(year(Report.Date)-2, 'And Prior')")
 return(data)
}

Debtors <- data.frame(Names = c("John", "Mary", "Charles", "Peter", "David", "Fabian", "Aggrey", "Elizabeth", "Anthony", "Catherine"), Amount = seq(from = 100000, by = 600, length.out = 10), Transaction.Date = seq.Date(from = as.Date("2016/1/1"), by = "quarter", length.out = 10))

Report.Date <- max(Debtors$Transaction.Date)

Aged.Data <- Aging(Debtors, Transaction.Date)

下面是我尝试创建但不起作用的 Shiny App:

library(shiny)
Aging <- function(data, Transaction.Date){
 if(missing(Transaction.Date)) stop("You forgot to specify Transaction Date")
 Transaction.Date <- deparse(substitute(Transaction.Date))
 data$year <- year(data[,Transaction.Date])
 data$Age <- car::recode(year(data[,Transaction.Date]), "year(Report.Date) = year(Report.Date); year(Report.Date)-1 = year(Report.Date)-1; else = paste(year(Report.Date)-2, 'And Prior')")
 return(data)
}

ui <- fluidPage(
dataTableOutput("Aged.Data")
)

server <- function(input, output) {
Data <- reactive({
Debtors <- data.frame(Names = c("John", "Mary", "Charles", "Peter", "David", "Fabian", "Aggrey", "Elizabeth", "Anthony", "Catherine"), Amount = seq(from = 100000, by = 600, length.out = 10), Transaction.Date = seq.Date(from = as.Date("2016/1/1"), by = "quarter", length.out = 10))

Report.Date <- max(Debtors$Transaction.Date)
Aged.Data <- Aging(Debtors, Transaction.Date)
})

output$Aged.Data <- renderDataTable(Data())

}

shinyApp(ui, server)

我得到的错误是:

in recode term:  else = paste(year(Report.Date)-2, 'And Prior')
message: Error in year(Report.Date) : object 'Report.Date' not found

我将非常感谢任何帮助。

约瑟夫。

【问题讨论】:

  • 在我包含所需的包lubridate之后,我运行它没有问题。
  • 谢谢,但如果您在确保初始“非闪亮”代码中没有残留对象后独立运行闪亮代码,则会引发我指出的错误。请尝试在新的 r 会话中仅运行闪亮的部分并确认它是否有效。谢谢

标签: r shiny


【解决方案1】:

这是一个简单的范围界定问题。

闪亮示例中的Aging 函数在全局范围内,它引用Report.Date。范围方面,Report.Date 只能从 Aging 访问,前提是它在函数本身中定义或者它也是一个全局变量。不闪亮的例子就是这种情况。

但在您的闪亮版本中,该变量仅在 server 函数内定义。 Agingserver 不共享任何变量。所以错误确实是,从全局范围的角度来看,Report.Date 不存在。

这里至少有三个选项:

  1. Aging 函数移动到server 函数中(作为子函数),以便Aging 可以访问server 的范围。
  2. Report.Date 移出server 作用域到全局作用域,并使用&lt;&lt;- 而不是&lt;- 将其从server 更改。 (用于在超级作用域中分配变量的键。)
  3. Report.Date 设为函数调用中的参数,而不是范围外的变量。然后,在 server 内,您可以使用所需的值调用它 Report.Date

基于这个简单的例子,我会说第三种解决方案是最干净的。

如果您需要更多解释,请随时发表评论。

【讨论】:

  • 非常感谢@K.Rohde。我发现将 Report.Date 移动到全局范围的解决方案 2 在我的具体问题中是最整洁的。非常感谢。
  • @JosephKigotho 请注意,全局变量在所有闪亮会话之间共享,即打开此应用程序的人。所以其他用户也可以更改相同的Report.Date
  • 按照@K.Rohde 上面的警告说明,我尝试实施解决方案 3,在该解决方案中我成功地重写了 Aging 函数以包含 Report.Date 作为参数。然后我在 UI 中添加了一个dateInput,让每个用户选择他们唯一的Report.Date。然而,似乎我仍然不得不求助于全局赋值运算符将用户输入作为参数分配给 Aging 函数。我在这里重写了新问题:link。我希望避免覆盖 Report.Date 参数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-14
  • 1970-01-01
  • 2014-05-13
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多