如何用Shiny中的dplyr反应性地定义第一列

时间:2016-10-27 09:31:02

标签: r shiny dplyr

假设我想要一个用户上传的数据集,类似于我的Shiny应用程序中R提供的二氧化碳数据集。我正在寻找人们加载这种类型的数据集,然后使用dplyr的mutate从现有数据集中生成一个新值。我编写了反应值来检查数据中是否存在“浓缩”和“吸收”,如果是,则使用它们来生成新值。

然后我想要一个新的表格,显示第一列(标识样本)和这个新值。但是,由于数据集将根据用户输入而改变,因此我无法指定列(对于CO2数据集,它将是“植物”)。

这是我的玩具示例:

library(shiny)
library(dplyr)

ui <- pageWithSidebar(
  headerPanel("Test"),
  sidebarPanel(
    fileInput('file1', 'Choose CSV File',
              accept=c('text/csv',
                       'text/comma-separated-values,text/plain',
                       '.csv')),
    tags$hr(),
    checkboxInput('header', 'Header', TRUE),
    radioButtons('sep', 'Separator',c(Comma=',',Semicolon=';',Tab='\t'),',')
  ),
  mainPanel(
    tableOutput("inputfile"),
    tableOutput("do")
  )
)

server <- function(input, output, session) {

  upData <- reactive({
    if(is.null(input$file1)) return(CO2)
    inFile <- input$file1
    dat <- read.csv(inFile$datapath)
    return(dat)
  })

output$inputfile <- renderTable({
    head(upData())
  })

  concvar <- reactive({
    if("conc" %in% colnames(upData())==TRUE) {upData()$conc} 
    else{0} 
  })

  uptakevar <- reactive({
    if("uptake" %in% colnames(upData())==TRUE) {upData()$uptake} 
    else{0} 
  })

  newvalue <- reactive({
    upData() %>% 
      mutate(newvalue=concvar()/uptakevar()) %>% 
      select(newvalue)
  })

  output$do <- ({
    renderTable(head(newvalue()))
  })

}

shinyApp(ui = ui, server = server)

这几乎可以实现我想要的一切,但我无法弄清楚如何让这个新的值列也有一个标识相应样本的列。

我尝试在“newvalue”dplyr链中定义upData()[,1]并使用select_,但我一直在收到错误。如何在select调用中反应性地定义各种假设数据集的第一列,以便我的新值使用样本名称进行上下文化?

1 个答案:

答案 0 :(得分:1)

问题是您的concvaruptakevar函数正在返回值的完整向量,但您尝试将它们视为列名。或者,直接使用这样的向量:

newvalue <- reactive({
  data.frame(
    newvalue = concvar() / uptakevar()
  )
})

或者,返回列名,然后使用mutate_构建感兴趣的列,如下所示。请注意,除了select_之外,我还使用了newvalue来选择第一列。将它定义为一个字符(比如你的conc和uptake变量)可能会更好,以允许用户选择一个合理的ID列来包含(而不是假设第一列是一个ID)。

concvar <- reactive({
  if("conc" %in% colnames(upData())==TRUE) {"conc"} 
  else{0} 
})

uptakevar <- reactive({
  if("uptake" %in% colnames(upData())==TRUE) {"uptake"} 
  else{0} 
})

newvalue <- reactive({
  upData() %>%
    mutate_(newvalue = paste(concvar(), "/", uptakevar())) %>% 
    select_(names(upData())[1], "newvalue")
})

我会推荐后者,因为我假设你打算使用某种选择框让用户选择要使用的列名(这将返回带有列名的字符向量)。