我正试图将行索引列添加到从用户输入实时创建的反应性数据框架中。我能够使用tibble::rowid_to_column函数在Shiny之外做到这一点,但不能使其在下面的Shiny应用程序(第44行)中工作。有人能就如何使其工作提供指导吗?此外,当我从数据帧中删除一行时,我们如何使行号再次顺序?谢谢。
library(shiny)
library(DT)
library(tidyverse)
input_data <- data.frame(
# rowid = double(),
input1 = character(),
input2 = double(),
stringsAsFactors = FALSE)
ui <- fluidPage(
titlePanel("Title"),
sidebarLayout(
sidebarPanel(
selectInput("input1",
"Input 1",
choices = c("Value 1", "Value 2", "Value 3")),
numericInput("input2",
"Input 2",
value = 100),
actionButton("add_btn",
"Add Row"),
actionButton("delete_btn",
"Delete Row"),
actionButton("reset_btn",
"Reset"),
position = "left"
),
mainPanel(
DT::dataTableOutput("input_table")
)
)
)
server <- function(input, output) {
input_table <- reactiveVal(input_data)
observeEvent(input$add_btn, {
t = rbind(input_table(), data.frame(col1 = input$input1, col2 = input$input2))
# %>%
# cbind(tibble::rowid_to_column("rowid"))
input_table(t)
})
observeEvent(input$delete_btn, {
t = input_table()
print(input$input_table_rows_selected)
if (!is.null(input$input_table_rows_selected)) {
t <- t[-input$input_table_rows_selected,]
}
input_table(t)
})
observeEvent(input$reset_btn, {
input_table(input_data)
})
output$input_table <- DT::renderDataTable({
datatable(input_table())
})
}
shinyApp(ui = ui, server = server)
rowid_to_column()
添加标题的行名,并将它们作为列添加到数据框架中。这对您不起作用:一旦在列rowid
中添加了行名,就不能第二次添加该列。此外,该函数返回添加了新列的整个目录,因此cbind()
对rowid_to_column()
的输出没有任何意义。
我建议对你的代码做如下修改:
用rowid列定义初始表:
input_data <- tibble(
rowid = integer(),
input1 = character(),
input2 = double()
)
在第一个观察者中,将代码更改为:
observeEvent(input$add_btn, {
new_row <- tibble(rowid = nrow(input_table()) + 1,
input1 = input$input1,
input2 = input$input2)
t = bind_rows(input_table(), new_row)
input_table(t)
})
这将创建一个具有适当行号的新行,然后将其添加到表中。
为了在删除行后获得预期的行,您只需在每次删除行时重新定义行:
observeEvent(input$delete_btn, {
t <- input_table()
print(input$input_table_rows_selected)
if (!is.null(input$input_table_rows_selected)) {
t <- t[-input$input_table_rows_selected, ]
# reset the rowids only, when there is at least one row left
if (nrow(t) > 0) {
t$rowid <- 1:nrow(t)
}
}
input_table(t)
})
在呈现输出表时,必须抑制行名:
output$input_table <- DT::renderDataTable({
datatable(input_table(), rownames = FALSE)
})