我正在尝试将条件趋势线添加到绘图中。选择1或2个复选框时,下面的代码有效,但选择0复选框时则不行。如何返回仍满足参数的空行或空行?我已尝试返回geom_blank()
并返回NULL
。
当选中0复选框时,以下代码将返回错误:
Warning in is.na(e2) :
is.na() applied to non-(list or vector) of type 'NULL'
Warning: Error in eval: incorrect length (0), expecting: 100
我应该补充一点,我的真实应用程序有许多不同的复选框组,因此在实际绘图创建中添加条件是不可行的。
app.R
library(shiny)
library(ggplot2)
library(plotly)
df1 <- as.data.frame(list('user'=c(rep('A',50),rep('B',50)),'x'=1:100,'y'=rnorm(100)))
ui <- fluidPage(
sidebarLayout(
# select a user
sidebarPanel(
checkboxGroupInput("userInput","User",
choices=sort(unique(df1$user)),
selected='A')
),
# plot selected user in plotly
mainPanel(
plotlyOutput("mainPlot")
)
)
)
server <- function(input, output, session) {
output$mainPlot <- renderPlotly({
# filter based on selected user
filteredForUser <- reactive({
df1 %>%
filter(
user == input$userInput
)
})
# add a trend line based on user
addTrendLine <- reactive({
if (is.null(filteredForUser())) {
return(geom_blank())
}
g <- geom_smooth(data=filteredForUser(), aes(x=x,y=y), method='lm')
return(g)
})
# create a plot
g <- ggplot(data=df1, aes(x=x,y=y)) + geom_line() + addTrendLine()
ggplotly(p=g)
})
}
shinyApp(ui, server)
答案 0 :(得分:1)
这是另一种方法,因为你不想在无功输入上使用条件。在此示例中,如果没有勾选任何复选框,df1 %>% filter(user == input$unserInput)
将返回错误。
我只是更改了代码的is.null()
部分,以检查filteredForUser
的类。
输出类似于@ Gopala的解决方案。希望这对你有用吗?
server <- function(input, output, session) {
output$mainPlot <- renderPlotly({
# filter based on selected user
filteredForUser <- reactive({
try(
df1 %>%
filter(
user == input$userInput
), silent = T)
})
# add a trend line based on user
addTrendLine <- reactive({
if (class(filteredForUser()) == "try-error") {
return(geom_blank())
}else{
g <- geom_smooth(data=filteredForUser(), aes(x=x,y=y), method='lm')
return(g)
}
})
# create a plot
g <- ggplot(data=df1, aes(x=x,y=y)) + geom_line() + addTrendLine()
ggplotly(p=g)
})
}
答案 1 :(得分:0)
问题是filteredForUser
的被动不处理空案例。此外,您需要有条件地添加到ggplot
对象。请尝试使用此代码或其中的一些变体:
server <- function(input, output, session) {
output$mainPlot <- renderPlotly({
# filter based on selected user
filteredForUser <- reactive({
if (is.null(input$userInput)) {return(df1)}
df1 %>%
filter(
user == input$userInput
)
})
# add a trend line based on user
getPlot <- reactive({
g <- ggplot(data = df1, aes(x=x, y=y)) + geom_line()
if (nrow(filteredForUser()) == nrow(df1)) {
return(g)
}
g <- g + geom_smooth(data=filteredForUser(), aes(x=x, y=y), method='lm')
return(g)
})
# create a plot
g <- getPlot()
ggplotly(p=g)
})
}