2015-11-14 213 views
0

我已经搜查相当长一段时间了,但我还没有找到一个解决我的问题不同类型的表格输入。我建立一个项目管理应用程序,我想使用有光泽,因为我认为这将能够使应用程序更具交互性。[R闪亮:动态创建

因此应用程序的输入应该在应用程序内完成。输入将是数字,文本和选择。对于概述,属于一起的输入应排列在一行中。例如:

resource_1,NAME = '共聚焦显微镜',键入= '机',价格= 1000,价格类型= 'EUR /使用'

我想安排在一个表格中的每个条目。当然,条目的数量是可变的。有时你可能会为某个项目定义5个资源,有时候是50个。

为了解决这个问题,我创建了一个闪亮的html表格作为表格条目。但是,我需要动态访问这些条目。我想我能做到这一点通过调用的get()函数中的每个表项的输入ID的字符串。但那不行。

目前:

  • 我可以创建具有不同类型的输入和行的可变数量的表格。

  • 我可以通过实际调用输入ID(如“输入$ element1_1”

  • 相互调用这些输入,但我不能让一个循环来自动获取这些输入标识的,像get()方法:得到(paste0( '输入$元素',我, '_',J))

小例子:

library(shiny) 

ui = 
    pageWithSidebar(

headerPanel("TEST"), 

sidebarPanel(
    helpText("number of resources"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    bsButton('finish_res',"finish",width='100%',style="info"), # check matrix 
    width=2 
), 

mainPanel( 
    uiOutput('matrix_res'), 
    p("make an entry in row1 col1 and press finish"), 
    br(), 
    p("I can extract elements by calling input$element1_1:"), 
    textOutput('check1'), 
    br(), 
    p("but not by searching for the character string with get('element1_1') "), 
    textOutput('check2') 
) 
) 

server = 
    function(input,output){ 

output$matrix_res <- renderTable({ 

    input$create_res #create button dependency 


    Row_entries <- paste("ressource",1:isolate(input$nres)) #kill nres dependency 
    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:length(Row_entries)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value=''>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value=''>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'> 
          <div> 
          <select id='element", i, "_", 3, "' class='form-control'><option value='a' selected>a</option> 
          <option value='b'>b</option></select> 
          <script type='application/json' data-for='element", i, "_", 3, "'>{}</script> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 

    },sanitize.text.function = identity) 


output$check1<-renderText({ 
    input$finish_res 
    isolate(input$element1_1) 
}) 

output$check2<-renderText({ 
    input$finish_res 
    isolate(input$get('element1_1')) 
}) 
} 

runApp(list(ui = ui, server = server)) 

运行:您可以通过更改的行数号码输入和创建按钮。您可以通过点击完成调用ROW1列1的值。

如果您有任何想法如何获得这些输入,请回复。我卡在这个狗屎已经一个星期...

回答

0

所以我找到了一个令人不满意的答案。 我使用get(),eval()函数,do.call()和下面的实际工作试图围绕:

的eval(解析(文= character_string))

这样就可以使character_string < - paste0( 'input $ element',i,'_',j)或者其他东西

所以,通过这个,你可以创建一个循环遍历所有的输入并为所有输入创建一个列表。其实,我希望它可以将所有的输入直接保存到列表中。

所以这里有一个例子:

library(shiny) 

ui = 
pageWithSidebar(

headerPanel("TEST"), 

sidebarPanel(
    helpText("number of rows"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    helpText("show me value in row 1 column 1"), 
    actionButton('finish_res',"show",icon=icon("check"),width='100%'), 
    width=2 
), 

mainPanel( 
    uiOutput('matrix_res'), 
    p("just by actually writing 'input$element1_1'"), 
    textOutput('check1'), 
    br(), 
    p("with get(character_string)"), 
    textOutput('check2'), 
    br(), 
    p('with eval(parse(text=character_string)):'), 
    textOutput('check3'), 
    br(), 
    p('with do.call("print", list(as.name(character_string)))'), 
    textOutput('check4') 
) 
) 

server = 
function(input,output){ 

output$matrix_res <- renderTable({ 

    input$create_res #create button dependency 


    Row_entries <- paste("ressource",1:isolate(input$nres)) #kill nres dependency 
    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:length(Row_entries)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value=''>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value=''>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'> 
          <div> 
          <select id='element", i, "_", 3, "' class='form-control'><option value='a' selected>a</option> 
          <option value='b'>b</option></select> 
          <script type='application/json' data-for='element", i, "_", 3, "'>{}</script> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 

    },sanitize.text.function = identity) 


output$check1<-renderText({ 
    input$finish_res 
    isolate(input$element1_1) 
}) 

output$check2<-renderText({ 
    input$finish_res 
    isolate(get(paste0('input$element',1,'_',1))) 
}) 

output$check3<-renderText({ 
    input$finish_res 
    isolate(eval(parse(text=paste0('input$element',1,'_',1)))) 
}) 

output$check4<-renderText({ 
    input$finish_res 
    isolate(do.call("print", list(as.name(paste0('input$element',1,'_',1))))) 
}) 

} 

runApp(list(ui = ui, server = server)) 
0

确定这里是得到我想要的东西的一种方式。

我确信有这样做的更好的方法,因为这对于一个简单的任务来说太复杂了。

请注意,如果您决定添加更多行,则会保存输入。

library(shiny) 

ui <- 
pageWithSidebar(

headerPanel("Dynamic table for Input of different types"), 

sidebarPanel(
    helpText("number of rows"), 
    numericInput("nres","",3,min=0), 
    actionButton('create_res',"create",icon=icon("plus"),width='100%'), 
    br(), 
    br(), 
    br(), 
    helpText("read input you entered"), 
    actionButton('finish_res',"finish",icon=icon("check"),width='100%'), 
    width=2 
), 

mainPanel( 
    h3("input table"), 
    uiOutput('matrix_res'), 
    h3("output table"), 
    tableOutput('check_table'), 
    br() 

) 
) 

server <- 
function(input,output){ 


# input table 
# table with different types of input 
# row number can be changed with number input 
# changes are applied after pressing create button 
output$matrix_res <- renderTable({ 

    input$create_res # dependency 


    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    for (i in 1:isolate(input$nres)) { 
    matrix[i,1] <- paste0("<input id='element", i, "_", 1, "' class='shiny-bound-input span6' type='text' value='",input[[paste0("element", i, "_", 1)]],"'>") 
    matrix[i,2] <- paste0("<input id='element", i, "_", 2, "' class='shiny-bound-input span6' type='number' value='",input[[paste0("element", i, "_", 2)]],"'>") 
    matrix[i,3] <- paste0("<div class='form-group shiny-input-container'><div> 
          <select id='element", i, "_", 3, "' class='form-control'> 
          <option value='a'>a</option> 
          <option value='b'>b</option> 
          </div></div>") 
    } 

    colnames(matrix) <- Col_entries 

    matrix 


    },sanitize.text.function = identity) 




# change row number for output table 
# only if new input table is created with create button 
row_number<-reactive({ 
    input$create_res # dependency 
    isolate(input$nres) 
}) 




# output table 
# object created when clicking on finish button 
# only dependent on finish button 
output_table<-reactive({ 

    input$finish_res # dependency 

    Col_entries <- c("text input","number input","selection") 

    matrix <- data.frame() 

    isolate(
    for (i in 1:isolate(row_number())) { 
     matrix[i,1] <- input[[paste0('element',i,'_',1)]] 
     matrix[i,2] <- input[[paste0('element',i,'_',2)]] 
     matrix[i,3] <- input[[paste0('element',i,'_',3)]] 
    } 
) 
    colnames(matrix) <- Col_entries 

    matrix 

}) 


# show output table 
output$check_table<-renderTable({ 
    if(input$finish_res == 0) return() #hide it on start 
    output_table() 
}) 

} 


runApp(list(ui = ui, server = server))