【问题标题】:Using numeric inputs to generate datatable in R shiny使用数字输入在 R Shiny 中生成数据表
【发布时间】:2021-10-27 15:52:28
【问题描述】:

我正在尝试制作一个闪亮的应用程序,用户将在其中输入将用于生成表格的值。我有输入的代码:

ui <- fluidPage(
  numericInput("HomePrice", "Home Price", value = "", min = 0, max = NA, step = 50),
  numericInput("DownPaymentDollars", "Downpayment (Dollars)", value = "", min = 0, max = NA, step = 50, width = NULL),
  numericInput("DownPaymentPercent", "Downpayment (Percent)", value = "", min = 0, max = 100, step = 0.05, width = NULL),
  numericInput("LoanAmount", "Loan Amount", value = "", min = 0, max = NA, step = 50, width = NULL),
  numericInput("InterestRate", "Interest Rate", value = "", min = 0, max = NA, step = 0.0005, width = NULL),
  numericInput("TermYears", "Term (Years)", value = "", min = 0, max = NA, step = 0.5, width = NULL),
  numericInput("MonthlyPrincipleInterest", "Monthly Principle + Interest", value = "", min = 0, max = NA, step = 0.005, width = NULL),
  numericInput("PMIRate", "Annual PMI Rate", value = "", min = 0, max = NA, step = 0.0005, width = NULL),
  numericInput("MonthlyPMI", "Monthly PMI (Escrow)", value = "", min = 0, max = NA, step = 0.005, width = NULL),
  numericInput("MonthlyTaxes", "Monthly Taxes (Escrow)", value = "", min = 0, max = NA, step = 0.005, width = NULL),
  numericInput("MonthlyEscrow", "Monthly Escrow", value = "", min = 0, max = NA, step = 0.005, width = NULL),
  numericInput("MinimumPayment", "Minimum Monthly Payment", value = "", min = 0, max = NA, step = 0.005, width = NULL),
  numericInput("ExtraMonthlyPayment", "Extra Monthly Payment", value = "", min = 0, max = NA, step = 0.005, width = NULL)
)

我还有一些用于更新用户输入的代码(例如在美元和百分比之间交替):

    server = function(input, output, session){
      
      observeEvent({
        input$HomePrice
        input$DownPaymentDollars
      }, {
        updateNumericInput(session, "DownPaymentPercent", value = input$DownPaymentDollars * 100 / input$HomePrice)
      })
      
      observeEvent({
        input$HomePrice
        input$DownPaymentPercent
        }, {
        updateNumericInput(session, "DownPaymentDollars", value = input$DownPaymentPercent * input$HomePrice / 100)
      })
      
      observeEvent({
        input$HomePrice
        input$DownPaymentDollars
      }, {
        updateNumericInput(session, "LoanAmount", value = input$HomePrice - input$DownPaymentDollars)
      })
      
      observeEvent({
        input$LoanAmount
        input$InterestRate
        input$TermYears
      }, {
        updateNumericInput(session, "MonthlyPrincipleInterest", value = input$LoanAmount*((input$InterestRate/100/12)*((1+(input$InterestRate/100/12))^(input$TermYears*12)))/(((1+(input$InterestRate/100/12))^(input$TermYears*12))-1))
      })
      
      observeEvent({
        input$LoanAmount
        input$PMIRate
      }, {
        updateNumericInput(session, "MonthlyPMI", value = (input$PMIRate / 100) / 12 * input$LoanAmount)
      })
      
      observeEvent({
        input$LoanAmount
        input$MonthlyPMI
      }, {
        updateNumericInput(session, "PMIRate", value = input$MonthlyPMI / input$LoanAmount * 12 * 100)
      })
    
      observeEvent({
        input$MonthlyPMI
        input$MonthlyTaxes
      }, {
        updateNumericInput(session, "MonthlyEscrow", value = input$MonthlyPMI + input$MonthlyTaxes)
      })
      
      observeEvent({
        input$MonthlyPrincipleInterest
        input$MonthlyEscrow
      }, {
        updateNumericInput(session, "MinimumPayment", value = input$MonthlyPrincipleInterest + input$MonthlyEscrow)
      })
}

我还有使用输入创建数据框的代码(虽然我还没有让它在闪亮的应用程序中工作,当所有 input$IDs 只是变量时它工作得很好:

  observeEvent({
    input$TermYears
    input$LoanAmount
    input$MonthlyPMI
    input$MonthlyTaxes
    input$InterestRate
    input$MonthlyPrincipleInterest
    input$ExtraMonthlyPayment
    input$HomePrice
  }, {
    Month <- seq(1, input$TermYears*12, 1)
    df <- data.frame(Month)
    df$PreviousBalance <- input$LoanAmount
    df$PMI <- input$MonthlyPMI
    df$Taxes <- input$MonthlyTaxes
    df$Interest <- df$PreviousBalance*(input$InterestRate/100/12)
    df$Principal <- input$MonthlyPrincipleInterest-df$Interest+input$ExtraMonthlyPayment
    df$EquityDollars <- input$HomePrice-df$PreviousBalance+df$Principal
    df$EquityPercent <- (df$EquityDollars/input$HomePrice)*100
    df$EndingBalance <- df$PreviousBalance-df$Principal
    x <- seq(1, input$TermYears*12, 1)
    for (i in x) {
      if(i > 1) {
        df$PreviousBalance[i] <- df$EndingBalance[i-1]
        if(df$EquityPercent[i-1]<20) {
          df$PMI[i] <- input$MonthlyPMI
        }
        else {
          df$PMI[i] <- 0
        }
        df$Taxes[i] <- input$MonthlyTaxes
        df$Interest[i] <- df$PreviousBalance[i]*(input$InterestRate/100/12)
        if(df$PreviousBalance[i]>df$Principal[i]) {
          df$Principal[i] <- input$MonthlyPrincipleInterest-df$Interest[i]+input$ExtraMonthlyPayment
        }
        else {
          df$Principal[i] <- df$PreviousBalance[i]
        }
        df$EquityDollars[i] <- input$HomePrice-df$PreviousBalance[i]+df$Principal[i]
        df$EquityPercent[i] <- (df$EquityDollars[i]/input$HomePrice)*100
        df$EndingBalance[i] <- df$PreviousBalance[i]-df$Principal[i]
      }
    }
    
    
  })

这是我第一次这样做,我如何为表格获取此代码并将其放入闪亮的应用程序中,以便一旦用户填写所有数字输入(并单击提交按钮)它会生成一个表格?

提前致谢。

【问题讨论】:

    标签: r shiny datatable render fluid


    【解决方案1】:

    要完成您的工作,您基本上只需要一个所谓的actionButton,这将是您的提交按钮,并让您的最后一个observeEvent 等待提交按钮。我已经在下面完成了您的代码。我还添加了print(df) 语句,以便您可以看到创建的表。为确保所有输入都有一个值,您还可以根据需要向req(input$IDs) 添加尽可能多的调用。我在下面的代码中只包含了一个 (req(input$TermYears))。

    library(shiny)
    
    
    # Define UI 
    ui <- fluidPage(
      numericInput("HomePrice", "Home Price", value = "", min = 0, max = NA, step = 50),
      numericInput("DownPaymentDollars", "Downpayment (Dollars)", value = "", min = 0, max = NA, step = 50, width = NULL),
      numericInput("DownPaymentPercent", "Downpayment (Percent)", value = "", min = 0, max = 100, step = 0.05, width = NULL),
      numericInput("LoanAmount", "Loan Amount", value = "", min = 0, max = NA, step = 50, width = NULL),
      numericInput("InterestRate", "Interest Rate", value = "", min = 0, max = NA, step = 0.0005, width = NULL),
      numericInput("TermYears", "Term (Years)", value = "", min = 0, max = NA, step = 0.5, width = NULL),
      numericInput("MonthlyPrincipleInterest", "Monthly Principle + Interest", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      numericInput("PMIRate", "Annual PMI Rate", value = "", min = 0, max = NA, step = 0.0005, width = NULL),
      numericInput("MonthlyPMI", "Monthly PMI (Escrow)", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      numericInput("MonthlyTaxes", "Monthly Taxes (Escrow)", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      numericInput("MonthlyEscrow", "Monthly Escrow", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      numericInput("MinimumPayment", "Minimum Monthly Payment", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      numericInput("ExtraMonthlyPayment", "Extra Monthly Payment", value = "", min = 0, max = NA, step = 0.005, width = NULL),
      actionButton("button", "Submit") # <=== here is the action button
    )
    
    server <- function(input, output, session){
      
      observeEvent({
        input$HomePrice
        input$DownPaymentDollars
      }, {
        updateNumericInput(session, "DownPaymentPercent", value = input$DownPaymentDollars * 100 / input$HomePrice)
      })
      
      observeEvent({
        input$HomePrice
        input$DownPaymentPercent
      }, {
        updateNumericInput(session, "DownPaymentDollars", value = input$DownPaymentPercent * input$HomePrice / 100)
      })
      
      observeEvent({
        input$HomePrice
        input$DownPaymentDollars
      }, {
        updateNumericInput(session, "LoanAmount", value = input$HomePrice - input$DownPaymentDollars)
      })
      
      observeEvent({
        input$LoanAmount
        input$InterestRate
        input$TermYears
      }, {
        updateNumericInput(session, "MonthlyPrincipleInterest", value = input$LoanAmount*((input$InterestRate/100/12)*((1+(input$InterestRate/100/12))^(input$TermYears*12)))/(((1+(input$InterestRate/100/12))^(input$TermYears*12))-1))
      })
      
      observeEvent({
        input$LoanAmount
        input$PMIRate
      }, {
        updateNumericInput(session, "MonthlyPMI", value = (input$PMIRate / 100) / 12 * input$LoanAmount)
      })
      
      observeEvent({
        input$LoanAmount
        input$MonthlyPMI
      }, {
        updateNumericInput(session, "PMIRate", value = input$MonthlyPMI / input$LoanAmount * 12 * 100)
      })
      
      observeEvent({
        input$MonthlyPMI
        input$MonthlyTaxes
      }, {
        updateNumericInput(session, "MonthlyEscrow", value = input$MonthlyPMI + input$MonthlyTaxes)
      })
      
      observeEvent({
        input$MonthlyPrincipleInterest
        input$MonthlyEscrow
      }, {
        updateNumericInput(session, "MinimumPayment", value = input$MonthlyPrincipleInterest + input$MonthlyEscrow)
      })
      
      # here you wait for the action button to be triggered
      observeEvent({input$button}, {
        req(input$TermYears)
        Month <- seq(1, input$TermYears*12, 1)
        df <- data.frame(Month)
        df$PreviousBalance <- input$LoanAmount
        df$PMI <- input$MonthlyPMI
        df$Taxes <- input$MonthlyTaxes
        df$Interest <- df$PreviousBalance*(input$InterestRate/100/12)
        df$Principal <- input$MonthlyPrincipleInterest-df$Interest+input$ExtraMonthlyPayment
        df$EquityDollars <- input$HomePrice-df$PreviousBalance+df$Principal
        df$EquityPercent <- (df$EquityDollars/input$HomePrice)*100
        df$EndingBalance <- df$PreviousBalance-df$Principal
        x <- seq(1, input$TermYears*12, 1)
        for (i in x) {
          if(i > 1) {
            df$PreviousBalance[i] <- df$EndingBalance[i-1]
            if(df$EquityPercent[i-1]<20) {
              df$PMI[i] <- input$MonthlyPMI
            }
            else {
              df$PMI[i] <- 0
            }
            df$Taxes[i] <- input$MonthlyTaxes
            df$Interest[i] <- df$PreviousBalance[i]*(input$InterestRate/100/12)
            if(df$PreviousBalance[i]>df$Principal[i]) {
              df$Principal[i] <- input$MonthlyPrincipleInterest-df$Interest[i]+input$ExtraMonthlyPayment
            }
            else {
              df$Principal[i] <- df$PreviousBalance[i]
            }
            df$EquityDollars[i] <- input$HomePrice-df$PreviousBalance[i]+df$Principal[i]
            df$EquityPercent[i] <- (df$EquityDollars[i]/input$HomePrice)*100
            df$EndingBalance[i] <- df$PreviousBalance[i]-df$Principal[i]
          }
        }
        print(df)
      })
    }
    
    shinyApp(ui = ui, server = server)
    
    

    【讨论】:

      猜你喜欢
      • 2017-05-17
      • 2018-07-15
      • 2017-03-16
      • 1970-01-01
      • 2016-07-08
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 2021-05-08
      相关资源
      最近更新 更多