topsis method for multiple decession making

here is a simple example of topsis() method

library(topsis)

# create a matrix with some random data
data <- matrix(runif(100), nrow = 10)
data
# define the criteria weights
w <- c(0.3, 0.4, 0.3,0.3,0.1,0.5,0.7,0.1,0.1,0.2)
im<- c('-','+','+','+','-','+','-','+','-','-')
# apply the MCDM method
result <- topsis(data, w,im)
result

so we need 3 parameters for the methods
the decision matrix, the weight vector, the impact vector

so in the shiny app, I create an editable matrix, fill the first row with weight and the last row with impacts.
but when I press the Ranking action button nothing happens.

```
---
title: "Themed dashboard"
output: 
  flexdashboard::flex_dashboard:
    theme:
      bg: "#101010"
      fg: "#FDF7F7" 
      primary: "#ED79F9"
      base_font:
        google: Prompt
      code_font:
        google: JetBrains Mono
    orientation: columns
    vertical_layout: fill
runtime: shiny      
---

```{r setup, include=FALSE}
library(flexdashboard)
# Install thematic and un-comment for themed static plots (i.e., ggplot2)
# thematic::thematic_rmd()
library(shiny)
library(DT)
library(topsis)
```

Column {.sidebar}
-----------------------------------------------------------------------

### Chart A

```{r}

      numericInput("num_hos", "Number of hospitals:", value = 2)
      numericInput("num_qua", "Number of quantities:", value = 2)
      actionButton("create", "Create an empty Matrix")
```



Column {data-width=350}
-----------------------------------------------------------------------

### Chart C

```{r}
data <- eventReactive(input$create,{
  matrix(nrow = input$num_hos+2,ncol = input$num_qua+1)
})

renderDataTable(data(),editable=list(target = "column"))

```

Column {data-width=350}
-----------------------------------------------------------------------

### Chart C

```{r}
first_row <- reactive({
  req(data())
  as.vector(data()[1,2:ncol(data())])
})

last_row <- reactive({
  req(data())
  as.vector(data()[nrow(data()),2:ncol(data())])
  

})
actionButton('Ranking','Ranking')
tops<-eventReactive(input$Ranking,{
  topsis(data(),first_row(),last_row())
})
renderTable(tops())
```

I think your approach is flawed, because you are trying to contain the weights (numbers) and impacts ( character symbols) in a matrix, and a matrix can only contain one consistent variable type. so it would be a character matrix.
I suppose you could proceed in this fashion, but you would need a step of turning the row of character weights to numeric.
Given that they are fundamentally different though, why try to have them in one matrix ? why not give each their own method of population ?

Someone helps me to create an editable matrix and it can be saved.

---
title: "Themed dashboard"
output: 
  flexdashboard::flex_dashboard:
    theme:
      bg: "#101010"
      fg: "#FDF7F7" 
      primary: "#ED79F9"
      base_font:
        google: Prompt
      code_font:
        google: JetBrains Mono
    orientation: columns
    vertical_layout: fill
runtime: shiny      
---

```{r setup, include=FALSE}
library(flexdashboard)
# Install thematic and un-comment for themed static plots (i.e., ggplot2)
# thematic::thematic_rmd()
library(shiny)
library(DT)
library(topsis)

Column {.sidebar}

Chart A


      numericInput("num_hos", "Number of hospitals:", value = 2)
      numericInput("num_qua", "Number of quantities:", value = 2)
      actionButton("create", "Create an empty Matrix")

Column {data-width=350}

Chart C

DTOutput("dtable", height = "200%")
dat <- NULL
data <- eventReactive(input$create, {
  dat <<- matrix(nrow = input$num_hos+2, ncol = input$num_qua+1)
  dat
})

output[["dtable"]] <- renderDT({
  datatable(
    data(), 
    editable = list(target = "cell"),
    extensions = "Buttons", 
    options = list(
      dom = 'Blfrtip', 
      buttons=c('copy', 'csv', 'excel', 'pdf', 'print'),
      lengthMenu = list(c(10, 25, 50, -1), c(10, 25, 50, "All"))
    )
  )
})

proxy <- dataTableProxy("dtable")

observeEvent(input[["dtable_cell_edit"]], {
  dat <<- editData(dat, input[["dtable_cell_edit"]], proxy, rownames = FALSE)
})

Column {data-width=350}

Chart C

fileInput("file2", "Choose CSV File",
                multiple = TRUE,
                accept = c("text/csv",
                         "text/comma-separated-values,text/plain",
                         ".csv"))


dataset<-eventReactive(input$file2,{
      datasets <<- read.csv(input$file2$datapath)
        matrix_datasets <<- as.matrix(datasets)
        return(matrix_datasets)
    })

renderTable({dataset()})

Chart D

actionButton('Rank','Ranking')

calculate_topsis <- eventReactive(input$Rank, {
    # Extract weights and impacts from  matrix
    weights <- as.numeric(matrix_datasets[1, 2:ncol( matrix_datasets)])
    impacts <- as.character( matrix_datasets[nrow( matrix_datasets), 2:ncol( matrix_datasets)])
   
    # Remove weights and impacts from the matrix before running topsis
    data1 <<-  matrix_datasets[-c(1,nrow(matrix_datasets)),-1 ]
    data2<<- as.numeric(data1)
    data3<<- matrix(data2,nrow = nrow(data1))
   
    result<-topsis(data3, weights, impacts)
    data.frame(row.names = rownames(result), result)
  })
renderTable({calculate_topsis()})

It works now, but some issues that make the app UserUnfriendly is that after filling the matrix, the user must save it as a CSV file and continue with the saved CSV file and the other problem is that the user can't change the names of the column.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.