我是R的新手(我不是程序员)并尝试创建一个交互式仪表板,用户可以在其中输入动态生成的文本输入框中的数字。我无法将这些输入捕获到一个合适的数据框中,我可以将其连接到其他数据并运行计算。
我按照这个example帮助我生成动态输入框并将它们捕获到数据框中,尽管我的情况有点不同。我的问题是关于接下来的步骤。创建输入后,我能够将它们放入我认为的数据框架中。我在数据中添加了行名称,以便在转置数据时它们可以成为列名。转置后,我从转置数据中删除了新的行名。我创建了新列,它们接受用户的输入,将它们转换为数字,然后执行一两个计算。我在下面包含了捕获问题的简化代码,可以在显示的数据表中看到。
library(shiny)
library(dplyr)
ui <- fluidPage(
selectInput("SelectControl", "Selector:", c("Method A", "Method B"), multiple=FALSE),
uiOutput("manualInputs"),
tableOutput("ListTable"),
DT::dataTableOutput("mytable1"),
DT::dataTableOutput("mytable2")
)
#End UI, Start Server----------------------------------------------------
server <- function(input, output) {
#In my full version, the months are dynamic, i.e. Jan2017, etc
uniqueMo <- data.frame(FISCAL_MONTH=c("Jan", "Feb", "Mar", "Apr"))
#Create the text input boxes dynamically
output$manualInputs <- renderUI({
NumberBoxes <- nrow(uniqueMo)
lapply(1:NumberBoxes, function(i){
monthout <- uniqueMo
textInput(paste(monthout[i,]), label=monthout[i,], value=0 ) })
})
#Try to place the results of the text inputs into a data frame
Llist <- reactive({
NumberB <- nrow(uniqueMo)
monthout <-uniqueMo
data.frame(lapply(1:NumberB, function(i) {input[[paste(monthout[i,]) ]] } ))
})
#Add row names so that they will become column names when I transpose
lister3 <- reactive({
lister4 <- Llist()
rownames(lister4) <- "inputs2"
lister4})
#Transpose the data and bind back to the list of months
lister5 <- reactive({t(lister3() ) })
lister6 <- reactive({cbind(uniqueMo, lister5() )})
#create a new column that equals the user inputs but which is numeric
lister7 <- reactive({mutate(lister6(), input=if(inputs2=="0") {0} else {as.numeric(levels(inputs2))[inputs2] } ) })
#And finally, two examples of calculations that behave strangely
lister8 <- reactive({mutate(lister7(), newcolumn=if(input==1) {input*100} else {input*2} ) })
lister9 <- reactive({mutate(lister7(), newcolumn2=if(input$SelectControl=="Method A") {input*100} else {input*2} ) })
#Display the results of the calculations for easy viewing
output$mytable1 <- DT::renderDataTable({lister8() })
output$mytable2 <- DT::renderDataTable({lister9() })
}
shinyApp(ui, server)
值得指出的两件事。在第一个数据表输出中,我希望如果我输入1,则“newcolumn”的相应行中的值为100.实际上,所有行都乘以100,具体取决于第一个输入框是否为1,而不是而不是“输入”列中的相应值是否为1.要查看我的意思,请在第一个框中键入1,然后在第二个框中键入2。然后尝试在第一个中键入2,在第二个中键入1。
其次,第二个图表显示错误:
评估错误:$运算符对原子向量无效。
很明显,我的结果并没有像我想象的那样处于正确的数据框架中。我知道lapply会创建列表,但我没有成功尝试转换为正确的数据框。我搜索并尝试了我能想到的一切。有人可以帮助我吗?
答案 0 :(得分:0)
我想这个问题源于if(input$SelectControl=="Method A")
语句,因为dataframe
有一个名为input
的列。只需将input$SelectControl
的值保存在变量中并与该变量进行比较就可以使代码正常工作。
您需要替换
lister9 <- reactive({mutate(lister7(), newcolumn2=if(input$SelectControl=="Method A") {input*100} else {input*2} ) })
在您的服务器中使用类似的内容
lister9 <- reactive({
selectControl <- input$SelectControl
mutate(lister7(), newcolumn2=if(selectControl=="Method A") {input*100} else {input*2} )
})
我想应该让你的代码有效。
希望它有所帮助!