2

1.Only the first/one number join in to the calculation loop, that not what I would like to get.

  1. For example,

when 2 class considered (K), there should be 2 responses (N1, N2), 2 means (M1, M2), and 2sd (Sd1, sd2).

Wmean=(N1*M1+N2*M2)/(N1+N2)
Weisd=(N1*sd1+N2*sd2)/(N1+N2-K)

But what I got is

Wmean=(N1*M1)/(N1)
Weisd=(N1*sd1)/(N1-K)

below are my codes, thanks in advance!

rm(list = ls())
library(shiny)


ui = (fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      numericInput("elemNb",
                   "No.of Class used", value = 2, min = 1,
                   max = 100),
      
      uiOutput("myUI0"),
      
      uiOutput("myUI1av"),
      uiOutput("myUI1dev")
      
    ),
    mainPanel(
      
      h4("General Evaluation:Weighted mean"),
      verbatimTextOutput("output1"),
      
      h4("General Evaluation:Pooled SD"),
      verbatimTextOutput("output2")
    )
  )
)
)

server = function(input, output) {
  
  output$myUI0=renderUI({
    
    response=""
    
    for (i in 1:input$elemNb){
      
      response=paste0(response,
                      numericInput(paste0("",i),
                                   inputId = "samplesize1",
                                   label = "No.of responses"))
      
    }
    HTML(response)})
  
  output$myUI1av=renderUI({
    
    GEav=""
    
    for (i in 1:input$elemNb){
      
      GEav=paste0(GEav,
                  numericInput(paste0("",i),
                               inputId = "Mean1",
                               label = "General Evaluation:'av.'"))}
    HTML(GEav)})
  
  output$myUI1dev=renderUI({
    
    GEdev=""
    
    for (i in 1:input$elemNb){
      
      GEdev=paste0(GEdev,
                   numericInput(paste0("",i),
                                inputId = "SD1",
                                label = "General Evaluation:'dev.'"))}
    HTML(GEdev)})
  
  
  rv <- reactive({
    
    
    tibble::tibble(
      
      sa_data1<-as.numeric(input$samplesize1),
      kc_data<-input$elemNb,
      
      me_data1<-as.numeric(input$Mean1),
      sd_data1<-as.numeric(input$SD1),
      
      General_evaluation_Weighted_mean=sum(sa_data1*me_data1)/sum(sa_data1),
      General_evaluation_Pooled_SD=(sqrt(sum((sa_data1-1)*sd_data1*sd_data1)))/((sum(sa_data1))-kc_data)
      
    )})
  
  output$output1 <- renderText({rv()$General_evaluation_Weighted_mean[1]})
  output$output2 <- renderText({rv()$General_evaluation_Pooled_SD[1]})
  
}
runApp(list(ui = ui, server = server))
Phil
  • 7,287
  • 3
  • 36
  • 66
Hang Jiang
  • 23
  • 4
  • Please fix the code formatting in your post, thank you – Ed_Gravy Nov 17 '22 at 18:40
  • 1
    Hold on, thank you so much for your reply. It's my first time to ask question here! – Hang Jiang Nov 17 '22 at 18:42
  • Thank you! See the new one, please! – Hang Jiang Nov 17 '22 at 18:47
  • What is this `paste0("", i)` in `numericInput`? And normally your `numericInput`s should throw an error because you don't set the `value` argument. – Stéphane Laurent Nov 17 '22 at 21:46
  • 1
    Ah I see, but your code is very puzzling. You use the same `inputId` for different `numericInput`s, that can't work. – Stéphane Laurent Nov 17 '22 at 21:50
  • Thank you! I agree. It's puzzling. I tried to use those different numericInput to do the following calculations. As you said, that can't work. Could you please give me any suggestions? Thank you in advance. By the way, the source code from here. https://stackoverflow.com/questions/32718436/shiny-r-renderprint-in-loop-usinf-renderui-only-update-the-output – Hang Jiang Nov 17 '22 at 21:54

1 Answers1

1

Not tested but that looks correct:

library(shiny)


ui <- fluidPage(
  
  sidebarLayout(
    sidebarPanel(
      numericInput("elemNb",
                   "No.of Class used", value = 2, min = 1,
                   max = 100),
      
      uiOutput("myUI_sampleSizes"),
      uiOutput("myUI_means"),
      uiOutput("myUI_sds")
    ),
    
    mainPanel(
      h4("General Evaluation:Weighted mean"),
      verbatimTextOutput("output1"),
      
      h4("General Evaluation:Pooled SD"),
      verbatimTextOutput("output2")
    )
  )
)


server <- function(input, output) {
  
  output$myUI_sampleSizes <- renderUI({
    
    response <- ""
    
    for(i in 1:input$elemNb) {
      response <- paste0(response,
                      numericInput(inputId = paste0("sampleSize", i),
                                   label = "No.of responses",
                                   value = 10))
    }
    
    HTML(response)
  })
  
  output$myUI_means <- renderUI({
    
    GEav <- ""
    
    for(i in 1:input$elemNb) {
      GEav <- paste0(GEav,
                  numericInput(inputId = paste0("mean", i),
                               label = "General Evaluation:'av.'",
                               value = 2))
    }
    
    HTML(GEav)
  })
  
  output$myUI_sds <- renderUI({
    
    GEdev <- ""
    
    for(i in 1:input$elemNb) {
      GEdev <- paste0(GEdev,
                      numericInput(inputId = paste0("sd", i),
                                   label = "General Evaluation:'dev.'",
                                   value = 1))
    }
    
    HTML(GEdev)
  })
  
  rv <- reactive({
    K <- input$elemNb
    sampleSizes <- sapply(1:K, function(i) input[[paste0("sampleSize", i)]])
    means       <- sapply(1:K, function(i) input[[paste0("mean", i)]])
    sds         <- sapply(1:K, function(i) input[[paste0("sd", i)]])
    
    list(
      "General_evaluation_Weighted_mean" = 
        sum(sampleSizes * means) / sum(sampleSizes),
      "General_evaluation_Pooled_SD"     = 
        sqrt(sum((sampleSizes-1) * sds^2)) / (sum(sampleSizes) - K)
    )
  })
  
  output$output1 <- renderText({rv()$General_evaluation_Weighted_mean})
  output$output2 <- renderText({rv()$General_evaluation_Pooled_SD})
  
}

shinyApp(ui, server)

EDIT

The problem is that the numeric inputs in the renderUIs are delayed. Here is a way to solve this issue:

  rv <- reactive({

    K <- input$elemNb
    
    for(i in 1:K) {
      test <- input[[paste0("sampleSize", i)]]
      if(is.null(test)) {
        return(NULL)
      }
    }
    
    sampleSizes <- sapply(1:K, function(i) input[[paste0("sampleSize", i)]])
    means       <- sapply(1:K, function(i) input[[paste0("mean", i)]])
    sds         <- sapply(1:K, function(i) input[[paste0("sd", i)]])
    
    list(
      "General_evaluation_Weighted_mean" = 
        sum(sampleSizes * means) / sum(sampleSizes),
      "General_evaluation_Pooled_SD"     = 
        sqrt(sum((sampleSizes-1) * sds^2)) / (sum(sampleSizes) - K)
    )
  })
Stéphane Laurent
  • 75,186
  • 15
  • 119
  • 225
  • Thank you so much for your help. The result looks correct, there are some errors: non-numeric argument to binary operator. I feel like need a very minor revise. – Hang Jiang Nov 17 '22 at 23:15