问题
I am building a shiny form which will take data from the textInput field and combined those input with a text file (which will be uploaded by file input) and show the output in the main panel. There is an action button to update the data for the first time (take the data from text input and merge with the processed text file) and I added another action button for add new data (the purpose of this Add new data to add a new set of data as row with the existing one, The new set of data will be uploaded by the file input). The sample data set is given below, which is a plain text formatted file. This sample dataset can be considered as the second text file. sample data:
# AREA ADC-MEAN ADC-STD DEV ADC-MIN ADC-MAX ADC-MED
1 12.0000 0.000644667 1.96669e-005 0.000606000 0.000671000 0.000644000
2 12.0000 0.000610250 1.43154e-005 0.000577000 0.000624000 0.000617000
I wrote shinnyApp based on the scenario. I am able to do update the text input and the text file output by merging and output as a table. But couldn't able to add a new set of data as rows. The script is given below:
library(shiny)
library(ggplot2)
library(xlsx)
library(xlsxjars)
library(rJava)
library(shinythemes)
# Define UI -----------
# ---------------------
ui <- fluidPage(theme = shinytheme("sandstone"),
# header
headerPanel("DTI post analysis conversion"),
sidebarLayout(
# sidebar for form
sidebarPanel(
h3("Information",""),
textInput("ani_id", "Patient ID",""),
textInput("scan_id", "Scan ID",""),
textInput("Tech_id", "Tech Id",""),
textInput("Age_weeks", "Age weeks",""),
fileInput("textfile", "Upload the text file"),
actionButton("update", "Update"),
helpText("Click to insert the data "),
br(),
actionButton("addEntry", "Add New Data"),
helpText("Click to insert new data "),
br(),
downloadButton("downloadData", "Download"),
helpText("Click for download the data (.csv) ")
),
# output for viewing
mainPanel(
DT::dataTableOutput("tableDT")
)
)
)
# Define server logic ------
# --------------------------
server <- function(input, output) {
# process the textinput
Frontal_Cortex_table <- eventReactive(input$update,{
# creating table
aniRoi2 <- data.frame(Animal_ID = rep(input$ani_id,2),
Scan_ID = rep(input$scan_id,2),
Tech_ID = rep(input$Tech_id,2),
Age_weeks = rep(input$Age_weeks,2),
stringsAsFactors = FALSE)
return(aniRoi2)
})
# process the text file and download
textdata <- eventReactive(input$update,{
file1 <- input$textfile
if(is.null(file1)){return()}
a <- read.table(file= file1$datapath,
sep="\t",
fill=FALSE,
strip.white=TRUE)[1:2,]
# Split the text file and shape as column
af <- as.character(a)
af1 <- matrix(unlist(strsplit(af, split=" +")), ncol=7, byrow =TRUE)
ad <- data.frame(af1[1:2,3:7])
colnames(ad)<- c("ADC_MEAN", "ADC_STD", "ADC_MIN", "ADC_MAX", "ADC_MED")
return(ad)
})
# merge two function as data.frame
mytable2 <-reactive({
dm = cbind.data.frame(Frontal_Cortex_table(), textdata())
})
# add new row (?)
addData <- observeEvent(input$addEntry, {
mytable2 <- isolate({
newLine <- reactive({cbind.data.frame(Frontal_Cortex_table(), textdata())})
rbind.data.frame(mytable2,newLine)
})
})
# output the data as table
output$tableDT <- DT::renderDataTable(
mytable2()
)
# download the file
output$downloadData <- downloadHandler(
filename = function() {
paste("DTI", "csv", sep = ".")
},
content = function(file) {
write.csv(mytable2(), file, row.names = FALSE)
}
)
}
# Run the app ----------
# ----------------------
shinyApp(ui = ui, server = server)
I have got the error message stating that :
Warning: Error in [[: object of type 'closure' is not subsettable Stack trace (innermost first):
73: rbind.data.frame
66: isolate
65: observeEventHandler [/Users/rahatjahan/Dropbox/Database dev/DTIApp/Ask questions.R#95]
1: runApp
I know, it's kind of long post but try to explain and provide everything so that there would not be any confusion.
Your comment and suggestions would be appreciated.
回答1:
The problem is solved, and each iteration it will add new rows. The new text data set:
# AREA ADC-MEAN ADC-STD DEV ADC-MIN ADC-MAX ADC-MED
1 12.0000 0.000644667 1.96669e-005 0.000606000 0.000671000 0.000644000
2 12.0000 0.000610250 1.43154e-005 0.000577000 0.000624000 0.000617000
3 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
4 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
5 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
6 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
7 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
9 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
10 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
# AREA FA-MEAN FA-STD DEV FA-MIN FA-MAX FA-MED
1 12.0000 0.233833 0.0171773 0.201000 0.262000 0.239000
2 12.0000 0.247417 0.0135275 0.220000 0.270000 0.248000
3 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
4 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
5 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
6 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
7 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
8 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
9 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
10 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
ADC-MEAN
0.000644667
0.000610250
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
ADC-STD DEV
1.96669e-005
1.43154e-005
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
FA-MEAN
0.233833
0.247417
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
FA-STD DEV
0.0171773
0.0135275
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
0.000000
And the modified code
library(shiny)
library(ggplot2)
library(xlsx)
library(xlsxjars)
library(rJava)
library(shinythemes)
# Define UI -----------
# ---------------------
ui <- fluidPage(theme = shinytheme("sandstone"),
# header
headerPanel("DTI post analysis conversion"),
sidebarLayout(
# sidebar for form
sidebarPanel(
h3("Information",""),
textInput("ani_id", "Patient ID",""),
textInput("scan_id", "Scan ID",""),
textInput("Tech_id", "Tech Id",""),
textInput("Age_weeks", "Age weeks",""),
fileInput("textfile", "Upload the text file"),
actionButton("update", "Insert 1st Data Set"),
helpText("Click to insert the data "),
br(),
fileInput("anothertextfile", "Upload another Text file"),
actionButton("addEntry", "Add New Data"),
helpText("Click to insert new data "),
br(),
actionButton("combine", "Combine the data sets"),
downloadButton("downloadData", "Download"),
helpText("Click for download the data (.csv) ")
),
# output for viewing
mainPanel(
DT::dataTableOutput("tableDT"),
DT::dataTableOutput("tableDT2")
)
)
)
# Define server logic ------
# --------------------------
server <- function(input, output) {
# process the textinput
Frontal_Cortex_table <- reactive({
# creating table
aniRoi2 <- data.frame(Animal_ID = rep(input$ani_id,2),
Scan_ID = rep(input$scan_id,2),
Tech_ID = rep(input$Tech_id,2),
Age_weeks = rep(input$Age_weeks,2),
stringsAsFactors = FALSE)
return(aniRoi2)
})
# process the text file and download
textdata <- reactive(
{
file1 <- input$textfile
if(is.null(file1)){return()}
#read.table(file=file1$datapath, sep=input$sep, header = input$header, stringsAsFactors = input$stringAsFactors)
a <- read.table(file= file1$datapath,
sep="\t",
fill=FALSE,
strip.white=TRUE)[1:20,]
# Split the text file and shape as column
af <- as.character(a)
#class(af)
#af
#nrow(a)
af1 <- matrix(unlist(strsplit(af, split=" +")), ncol=7, byrow =TRUE)
# typeof(af1)
# af1
ad <- data.frame(af1[1:2,3:7], af1[11:12, 3:7])
colnames(ad)<- c("ADC_MEAN", "ADC_STD", "ADC_MIN", "ADC_MAX", "ADC_MED",
"FA_MEAN", "FA_STD", "FA_MIN", "FA_MAX", "FA_MED")
return(ad)
})
# merge two function as data.frame
mytable2 <-eventReactive(input$update,{
dm <<- cbind.data.frame(Frontal_Cortex_table(), textdata())
})
# add new row (?)
addData1 <- eventReactive(input$addEntry, {
newLine <<- cbind.data.frame(Frontal_Cortex_table(), textdata())
})
addData <- eventReactive(input$addEntry, {
dm <<- rbind.data.frame(mytable2(),addData1())
})
addData2 <- eventReactive(input$addEntry, {
dm <<- rbind.data.frame(dm,addData1())
})
# output as data table
output$tableDT <- DT::renderDataTable(
mytable2()
)
# the combined data set with added row
output$tableDT2 <- DT::renderDataTable(
addData2()
)
# download the file
output$downloadData <- downloadHandler(
filename = function() {
paste("DTI", "csv", sep = ".")
},
content = function(file) {
write.csv(mytable2(), file, row.names = FALSE)
}
)
}
# Run the app ----------
# ----------------------
shinyApp(ui = ui, server = server)
Hope that will help.
来源:https://stackoverflow.com/questions/47083893/add-a-new-row-with-the-existing-data-frame-in-shiny-r-by-using-action-button