我试图使用Shiny输出来重新创建Hans Rosling著名的情节。在主面板上,我在没有任何警告的情况下将输出显示为空白。你能帮我指出我的错误吗?
library(gapminder)
library(ggplot2)
library(shiny)
library(dplyr)
ui <- shinyUI(fluidPage(
titlePanel("Life expectancy and GDP per capita from 1952 to 2007"),
sidebarLayout(
sidebarPanel(
p("Select year"),
sliderInput("yeartime",
label = "Year",
min = 1952,
max = 2007,
value = 1952,
animate = animationOptions(interval = 500, loop = TRUE)
)),
mainPanel(
plotOutput("Plot"),
)
)
))
continent_colours <-c(Africa = "#BF590CFF", Americas = "#F80039FF", Asia = "#600071FF",
Europe = "#3B9626FF", Oceania = "#4A51E0FF")
server <- shinyServer(function(input, output) {
output$Plot <- renderPlot({
p <- ggplot(gapminder, aes(x=lifeExp, y=gdpPercap, size = pop, color = continent))
+ geom_point(data = filter(gapminder,gapminder$year == input$yeartime), aes(lifeExp, gdpPercap, size = pop, color = continent_colours))
+ ylim(30,100)
+ labs(x="Life expectancy (years)", y = "GDP per capita (USD)", color = 'Continent',size = "Population (millions)")
})
})
shinyApp(ui = ui, server = server)
答案 0 :(得分:1)
从评论中看来,您无法很好地保护自己免受过滤问题的侵害。这是一个刺:
server <- shinyServer(function(input, output) {
thisdat <- eventReactive(input$yeartime, {
req(input$yeartime)
filter(gapminder, year == input$yeartime)
})
output$Plot <- renderPlot({
req(thisdat())
p <- ggplot(thisdat()) +
geom_point(aes(lifeExp, gdpPercap, size = pop, color = continent_colours)) +
ylim(30,100) +
labs(x="Life expectancy (years)", y = "GDP per capita (USD)", color = 'Continent',size = "Population (millions)")
print(p)
})
})
一些问题的演练:
不要在gapminder$
中使用filter
,而只使用列名。当您无所事事时,它会起作用,但会破坏dplyr
试图为您实现的某些效率,并且如果您进行任何分组或汇总,都将很难进行。
filter(gapminder, gapminder$year == input$yeartime) # wrong
filter(gapminder, year == input$yeartime) # right
使用req
测试(如闪亮的)“真实”数据。这样可以防止不完整的输入弄乱您的数据和/或绘图(seq ?req
)。例如,如果未设置input$yeartime
,因此NULL
,则thisdat
不会更新。同样,如果thisdat()
返回一个空的data.frame
,则会跳过其余的plot函数(这将使plot Vice变为空白,从而在控制台上显示错误)。
我将数据分解成自己的反应式块,以期您可能希望对数据做其他事情。例如,拥有一个小的汇总表和/或具有一些快速汇总统计信息的仪表板“卡片”并不少见。您所拥有的方式将要求该附加组件重新为其内容过滤数据。现在,任何想要查看要绘制哪些数据的东西都只能依赖于thisdat()
(看起来/作用就像一个函数),副作用是依赖于thisdat()
的任何东西也将受益。从单个req(input$yeartime)
中开始,不需要其他任何操作(除非在其他地方明确使用了此操作)。
我将数据对象从geom_point
移到了ggplot(...)
。您当然可以将其移回,但是除非您要使用gapminder
中未经过滤的数据,否则请坚持使用ggplot() + geom_point(data=thisdat(), aes(...)) + ...
。您无需为此可视化指定两次aes(...)
。 (无论哪种方式,您只需要列出一次数据即可。)
ggplot2
的细微差别,我在末尾添加了print(p)
。您尚未到达那里,但最终可能会需要它。
次要点,但我将+
全部移到了行的末尾,而下一行的开始。这也许有点风格,但是我知道有时候会导致解析器抱怨/中断。 (它也清除了大多数R友好编辑器中的缩进。)
我没有对您的ui
组件进行任何更改。
答案 1 :(得分:1)
您的代码存在一些问题。
首先,尝试在ggplot
中测试您的R
函数。在Shiny
中进行调试非常困难。
ui
中,您需要在plotOutput("Plot")
之后删除一个逗号ggplot
和geom_point
调用中使用相同的数据集。我刚刚创建了一个子集(gapminder_subset
),并在两个调用中都使用了它。 p
。没有分配,它将起作用+
元素的ggplot
符号不应位于换行符上。color
和size
。aes
的{{1}}中使用大陆色而不是单色,但是在这种情况下,指定的颜色应与输入数据的长度相同。或者(如Eli Berkow指出的),您可以使用geom_point
元素ggplot
添加颜色。这是工作示例:
scale_colour_manual