2014-05-02 88 views
3

我最近在閃亮的Google小組中發佈了類似的查詢,但沒有找到解決方案。我們正在開發一個Shiny應用程序,並且該主題表明我們在運行應用程序時遇到了「錯誤:下標越界」消息。但是,當我們隔離有問題的代碼並在RStudio中獨立運行代碼時,沒有錯誤。爲什麼Shiny中出現「下標越界」錯誤,但不是R?

這讓我想知道Shiny本身是否存在缺陷,或者我們是否缺少某些東西。

請參閱下面的說明以及產生錯誤的小例子。我們使用Shiny版本0.8.0和RStudio 0.98.501。

感謝您的幫助!


運行應用程序,將ui.R和server.R(見下文)的文件夾中,然後運行

library(shiny) 
runApp("<folder path>") 

它應該產生與左邊的按鈕的用戶界面,但在右邊你會看到「error:subscript out of bounds」。

但是,如果只是運行的代碼下面三行(大約57-59行中server.R)

show=data.frame(ps=c(4,-1,0,1),ns=c(0,1,0,0),ts=c(45842,15653,28535,21656)) 
best.fit1=regsubsets(ts~ps+ns,data=show,nvmax=1) 
pred1=predict.regsubsets(best.fit1,show,id=1) # line that offends Shiny 

在RStudio(需要包含的功能「predict.regsubsets」 - 在給定的server.R的開頭),那麼就沒有錯誤。

##################### 
## server.R 
##################### 

library(rms) 
library(leaps) 
library(shiny) 
library(datasets) 
library(stringr) 
library(ttutils) 
library(plyr) 
library(utils) 
library(ggplot2) 

# object is a regsubsets object 
# newdata is of the form of a row or collection of rows in the dataset 
# id specifies the number of terms in the model, since regsubsets objects 
# includes models of size 1 up to a specified number 
predict.regsubsets=function(object,newdata,id,...){ 
    form=as.formula(object$call[[2]]) 

    mat=model.matrix(form,newdata) 

    mat.dims=dim(mat) 
    coefi=coef(object,id=id) 
    xvars=names(coefi) 
    # because mat only has those categorical variable categories associated with newdata, 
    # it is possible that xvars (whose variables are defined by the "best" model of size i) 
    # has a category that is not in mat 
    diffs=setdiff(xvars,colnames(mat)) 
    ndiffs=length(diffs) 
    if(ndiffs>0){ 
    # add columns of 0's for each variable in xvars that is not in mat 
    mat=cbind(mat,matrix(0,mat.dims[1],ndiffs)) 
    # for the last "ndiffs" columns, make appropriate names 
    colnames(mat)[(mat.dims[2]+1):(mat.dims[2]+ndiffs)]=diffs 
    mat[,xvars]%*%coefi 
    } 
    else{ 
    mat[,xvars]%*%coefi 
    } 
} 

# Define server logic required to summarize and view the selected dataset 
shinyServer(function(input, output) { 

mainTable1 <- reactive({ 

    }) 

output$table21 <- renderTable({ 
    mainTable1() 
    }) 


formulamodel1 <- reactive({ 
    #ticketsale<-dataset1Input() 

    show=data.frame(ps=c(4,-1,0,1),ns=c(0,1,0,0),ts=c(45842,15653,28535,21656)) 
    best.fit1=regsubsets(ts~ps+ns,data=show,nvmax=1) 
    pred1=predict.regsubsets(best.fit1,show,id=1) 

    }) 

output$model1fit <- renderPrint({ 
    formulamodel1() 

    }) 

}) 

###################### 
## end server.R 
###################### 

###################### 
## ui.R 
###################### 

library(rms) 
library(leaps) 
library(shiny) 
library(datasets) 
library(stringr) 
library(ttutils) 
library(plyr) 
library(utils) 
library(ggplot2) 

shinyUI(pageWithSidebar(

headerPanel("Forecasting ticket sales for xxx"), 

sidebarPanel(
     p(strong("Model Fitting")), 

    selectInput("order1", "Sort results by:",c("a","b","c")), 
    submitButton("Run Model") 

    ), 

    mainPanel(

    h3(strong("Model fit without using ticket sales")), 
    tableOutput("table21"), 
    verbatimTextOutput(outputId = "model1fit") 

    ) 
)) 

回答

3

這三行看起來只在全局環境中執行時才起作用。如果你拿這個片段並在local({...})塊內運行它,你會看到同樣的錯誤。

錯誤來自predict.regsubsets的第一行,您在object$call[[2]]處查看。它是object$call,根據它是否在全球環境中執行而有很大不同;它的創建方法是leaps:::regsubsets.formula,請致電sys.call(sys.parent())。也許這需要是sys.call(sys.parent(0))(只是猜測)?

+0

喬,謝謝你的迴應。您正確識別了該問題。 Google小組中的某人能夠幫助我們。再次感謝。 – user3596572

0

感謝John Harrison爲了這個答案。他試圖通過閃亮的Google小組回覆,但該系統刪除了他的答案,以及稍後我發佈他的解決方案的嘗試。這裏是。


約翰·哈里森說:

的問題是與regsubsets功能:

> test_env <- new.env(parent = globalenv()) 
> with(test_env, {show=data.frame(ps=c(4,-1,0,1),ns=c(0,1,0,0),ts=c(45842,15653,28535,21656)) 
+     best.fit1=regsubsets(ts~ps+ns,data=show,nvmax=1) 
+     #pred1=predict.regsubsets(best.fit1,show,id=1) 
+     #pred1 
+     best.fit1}) 
Subset selection object 
Call: eval(expr, envir, enclos) 
2 Variables (and intercept) 
    Forced in Forced out 
ps  FALSE  FALSE 
ns  FALSE  FALSE 
1 subsets of each size up to 1 
Selection Algorithm: exhaustive 

你可以看到它得到它叫:輸出相對於環境及其在:

​​

rval$call <- sys.call(sys.parent())

是問題的代碼行


我回答說:

我在一個有點超過我的頭在這些R裏面的函數,環境等方面,我大致遵循以上,但我你的解釋不瞭解它有足夠的實際意義去解決它(或者它是否是可修復的)。你能否容易地指出我正確的方向?


約翰回答說:

你可以定義自己的regsubsets功能:

myregsubsets <- function (x, data, weights = NULL, nbest = 1, nvmax = 8, force.in = NULL, 
          force.out = NULL, intercept = TRUE, method = c("exhaustive", 
                     "backward", "forward", "seqrep"), really.big = FALSE, 
          ...){ 
    formula <- x 
    rm(x) 
    mm <- match.call() 
    mm$formula <- formula 
    mm$x <- NULL 
    mm$nbest <- mm$nvmax <- mm$force.in <- mm$force.out <- NULL 
    mm$intercept <- mm$method <- mm$really.big <- NULL 
    mm[[1]] <- as.name("model.frame") 
    mm <- eval(mm, sys.frame(sys.parent())) 
    x <- model.matrix(terms(formula, data = data), mm)[, -1] 
    y <- model.extract(mm, "response") 
    wt <- model.extract(mm, "weights") 
    if (is.null(wt)) 
    wt <- rep(1, length(y)) 
    else wt <- weights 
    a <- leaps:::leaps.setup(x, y, wt = wt, nbest = nbest, nvmax = nvmax, 
          force.in = force.in, force.out = force.out, intercept = intercept) 
    rval <- switch(1 + pmatch(method[1], c("exhaustive", "backward", 
             "forward", "seqrep"), nomatch = 0), stop(paste("Ambiguous or unrecognised method name :", 
                         method)), leaps:::leaps.exhaustive(a, really.big), leaps:::leaps.backward(a), 
       leaps:::leaps.forward(a), leaps:::leaps.seqrep(a)) 
    rval$call <- sys.call(sys.parent()) 
    rval$x <- formula 
    rval 
} 

predict.regsubsets=function(object,newdata,id,...){ 
    form=as.formula(object$x) 

    mat=model.matrix(form,newdata) 

    mat.dims=dim(mat) 
    coefi=coef(object,id=id) 
    xvars=names(coefi) 
    # because mat only has those categorical variable categories associated with newdata, 
    # it is possible that xvars (whose variables are defined by the "best" model of size i) 
    # has a category that is not in mat 
    diffs=setdiff(xvars,colnames(mat)) 
    ndiffs=length(diffs) 
    if(ndiffs>0){ 
    # add columns of 0's for each variable in xvars that is not in mat 
    mat=cbind(mat,matrix(0,mat.dims[1],ndiffs)) 
    # for the last "ndiffs" columns, make appropriate names 
    colnames(mat)[(mat.dims[2]+1):(mat.dims[2]+ndiffs)]=diffs 
    mat[,xvars]%*%coefi 
    } 
    else{ 
    mat[,xvars]%*%coefi 
    } 
} 

後來,約翰補充說:

的regsubsets功能假設用戶在呼喚它以某種方式。 myregsubsets是regsubsets.formula的替代品。在您的predict.regsubsets中,您使用as.formula(object$call[[2]])訪問公式。當嵌套在環境中時,這不會給你預期的東西。 myregsubsets替換使用rval$x <- formula獲得公式。然後改變的predict.regsubsets然後使用form=as.formula(object$x)而不是as.formula(object$call[[2]])