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.