Shiny应用中已定义变量Z未被识别问题求助
问题:Shiny中lme函数调用时变量Z未找到的解决办法
我在Shiny应用中尝试使用变量Z,但系统提示该变量不存在。明明在lme函数调用的前几行就定义了Z,为何Z的数值无法被保留?
应用代码
# # This is a Shiny web application. You can run the application by clicking # the 'Run App' button above. # # Find out more about building applications with Shiny here: # # http://shiny.rstudio.com/ # library(shiny) library(nlme) # Define UI for application that draws a histogram ui = fluidPage( titlePanel("Use csv"), sidebarLayout( sidebarPanel( fileInput('file1', 'Choose csv file', accept = c(".csv") ), sliderInput("p", "p:", min = -2, max = 3, value = 1), sliderInput("q", "q:", min = -2, max = 3, value = 2), ), mainPanel( plotOutput('sscPlot') ) ) ) server = function(input, output){ output$sscPlot<-renderPlot({ inFile <- input$file1 if(is.null(inFile)) return(NULL) file.rename(inFile$datapath, paste(inFile$datapath, ".csv", sep="")) df=read.csv(paste(inFile$datapath, ".csv", sep=""), 1) visit=df$visit K=round(length(unique(visit))/4) knots=quantile(unique(visit), seq(0.05, 0.95, length=K)) Z=outer(visit,knots,"-") Z=Z*(Z>0) model=lme(data=df, y ~ group + visit, random=list(group=pdIdent(~Z+-1), id=~1)) plot(1:10) }) } # Run the application shinyApp(ui = ui, server = server)
错误信息
Warning: Error in eval: object 'Z' not found
测试数据
structure(list(id = c(101, 102, 102, 103, 103, 103, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 107, 107, 107, 107, 107, 108, 108, 108, 108), visit = c(0, 0, 4, 0, 28, 27, 0, 20, 19, 15, 6, 0, 12, 29, 27, 14, 0, 15, 1, 26, 5, 0, 9, 28, 19, 3, 0, 19, 4, 6), y = c(-1, -1, -1, -1, 0, 0, -1, 0, -1, 0, 1, -1, 1, 0, 1, 0, -1, -1, -1, 0, -1, -1, -1, 1, -1, 0, -1, 0, 0, 1), group = structure(c(1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor")), row.names = c(NA, -30L), class = c("tbl_df", "tbl", "data.frame"))
原因与解决方法
原因
lme函数解析公式时,只会在data参数指定的数据框(此处为df)范围内查找变量。你定义的Z是独立于df的外部变量,因此函数无法在指定数据源中找到它,从而报错。
解决方法
将Z合并到数据框df中,让lme能从指定数据源读取该变量。修改后的server函数代码如下:
server = function(input, output){ output$sscPlot<-renderPlot({ inFile <- input$file1 if(is.null(inFile)) return(NULL) file.rename(inFile$datapath, paste(inFile$datapath, ".csv", sep="")) # 明确指定row.names参数,避免歧义 df=read.csv(paste(inFile$datapath, ".csv", sep=""), row.names = 1) visit=df$visit K=round(length(unique(visit))/4) knots=quantile(unique(visit), seq(0.05, 0.95, length=K)) Z=outer(visit,knots,"-") Z=Z*(Z>0) # 将Z合并到数据框df中 df <- cbind(df, Z) # 此时lme可从df中读取Z变量 model=lme(data=df, y ~ group + visit, random=list(group=pdIdent(~Z+-1), id=~1)) plot(1:10) }) }
补充说明
Z是矩阵类型,cbind后会自动将其列命名为Z.1、Z.2等,lme的公式~Z+-1会自动识别整个矩阵作为随机效应的设计矩阵,无需额外修改公式。- 原代码中
read.csv的第二个参数1建议明确写成row.names=1,避免因参数位置歧义导致的读取错误。
内容的提问来源于stack exchange,提问作者Vons
相关产品推荐
相关产品推荐

