使用Shiny将R数据加载到不同的环境中

时间:2016-02-17 18:28:22

标签: r shiny

我在ui.r端使用闪亮的fileInput(),允许用户读入两个不同的.Rdata文件,然后对这些文件执行操作。

问题是,当用户读入.Rdata file1时,它会保存一个名为" dat"的数据帧。第二个.Rdata还包含一个名为" dat"的数据帧。我无法解决这个问题,由于一段遗留代码,它总是如此。

所以我的目标是允许用户加载第一个.Rdata文件并访问名为" dat"并且还加载第二个.Rdata文件并访问名为dat的df,使得它们在整个用户会话的剩余时间内保持为两个独立的对象。

现在在我的server.R程序中,我读取了file1和file2,如下所示:

Rfile1 <- reactive({
    infile <- input$Rfile1
    sessionEnvir <- sys.frame()
    if (!is.null(input$Rfile1)) load(input$Rfile1$datapath, sessionEnvir)
})

Rfile2 <- reactive({
    infile <- input$Rfile2
    sessionEnvir <- sys.frame()
    if (!is.null(input$Rfile2)) load(input$Rfile2$datapath, sessionEnvir)
})  

observeEvent(input$doStuff, {   
    Rfile1 <- get(Rfile1())
    Rfile2 <- get(Rfile2())
    newDat <- merge(Rfile1, Rfile2, by.x = input$mergeKey1, by.y = input$mergeKey2)
... more stuff
    })  

所以这里发生的是Rfile2覆盖了Rfile1,它们都是一样的。

我尝试解决此问题的方法是尝试将.Rdata文件加载到不同的环境中,例如:

Rfile1 <- reactive({
    infile <- input$Rfile1
    e1 <- new.env()
    if (!is.null(input$Rfile1)) load(input$Rfile1$datapath, e1)
})

Rfile2 <- reactive({
    infile <- input$Rfile2
    e2 <- new.env()
    if (!is.null(input$Rfile2)) load(input$Rfile2$datapath, e2)
})  

observeEvent(input$doStuff, {   
    Rfile1 <- get(Rfile1(), envir = e1)
    Rfile2 <- get(Rfile2(), envir = e2)
    newDat <- merge(Rfile1, Rfile2, by.x = input$mergeKey1, by.y = input$mergeKey2)
... more stuff
    })  

但是,这似乎不起作用,使得两个文件Rfile1()和Rfile2()保持为我希望的单独文件。

任何人都可以指出我所犯的错误,使得Rfile1()和Rfile2()仍然可以作为它们的两个独立对象来访问吗?

以下是重现我遇到的问题的代码。首先,创建R文件,然后使用Shiny应用程序,您可以单独阅读它们。

如果您首先使用应用程序读取文件1并查看结构,则会将其读入。然后,如果您在file2中读取并查看结构,则也会将其读入。但是,如果您立即查看结构file1再次出现了,file2取代了它。

我尝试将数据加载并调用到不同的环境中,并且没有成功。所以,要么我做错了,要么我有更大的误解。

首先创建样本数据文件

dat <- data.frame(ID1 = 1:10, var2 = rnorm(10))
save(dat, file = 'file1.Rdata')
dat <- data.frame(ID2 = 1:10, var2 = rnorm(10))
save(dat, file = 'file2.Rdata')

ui.R

library(markdown)
workDir <- getwd()
shinyUI(navbarPage("Toolbar",
tabPanel("Merge Variables",
sidebarLayout(
  sidebarPanel( 

helpText("Choose the two data files to be merged.
    Each file must curently be formatted as .Rdata file"),

fileInput('Rfile1', 'Read in File 1', accept=c('.RData', '.Rda')),
fileInput('Rfile2', 'Read in File 2', accept=c('.RData', '.Rda')),

actionButton("foo1", "View data structure of F1"),
actionButton("foo2", "View data structure of F2"),

helpText("Choose the variables from each file to use as the merge key"),

uiOutput("mergeKey1"),
uiOutput("mergeKey2"),

textInput("new.data.name", label = "Save new .Rdata as:",
     value = paste(workDir, '/filename.Rdata', sep='')),

actionButton("MergeSave", "Merge and Save New Data")

), # end sidebar
    mainPanel(
    h1('Merge Variables Report'),
    verbatimTextOutput('mergeReport'),
    verbatimTextOutput('foo1'),
    verbatimTextOutput('foo2')
  )
)
  ) # end tabpanel for merge variables
)) # end program

server.R

options(shiny.maxRequestSize=100*1024^2) 
shinyServer(function(input, output, session) {

    Rfile1 <- reactive({
        infile <- input$Rfile1
        sessionEnvir <- sys.frame()
        if (!is.null(input$Rfile1)) load(input$Rfile1$datapath, sessionEnvir)
    })

    Rfile2 <- reactive({
        infile <- input$Rfile2
        sessionEnvir <- sys.frame()
        if (!is.null(input$Rfile2)) load(input$Rfile2$datapath, sessionEnvir)
    })  

    output$mergeKey1 <- renderUI({
        df1 <- get(Rfile1())
        if(is.null(df1)) return(NULL)
        nms1 <- names(df1)
        selectInput("mergeKey1","Select Merge Key From the Common Variables", nms1, multiple=FALSE, selectize = FALSE)
    })  

    output$mergeKey2 <- renderUI({
        df2 <- get(Rfile2())
        if(is.null(df2)) return(NULL)
        nms2 <- names(df2)
        selectInput("mergeKey2","Select Merge Key From the Common Variables", nms2, multiple=FALSE, selectize = FALSE)
    })      

    #observeEvent(input$MergeSave, {    
    output$mergeReport <- renderPrint({
        input$MergeSave     
        Rfile1 <- get(Rfile1())
        Rfile2 <- get(Rfile2())
        newDat <- merge(Rfile1, Rfile2, by.x = input$mergeKey1, by.y = input$mergeKey2)
        save(newDat, file = input$new.data.name)
        cat('All done:', '\n')
        })  

    output$foo1 <- renderPrint({
        input$foo1
        isolate({   
        Rfile1 <- get(Rfile1())
        str(Rfile1)
        })   
    })      

    output$foo2 <- renderPrint({
        input$foo2
        isolate({   
        Rfile2 <- get(Rfile2())
        str(Rfile2)
        })   
    })          
}) # end Program

0 个答案:

没有答案