目标:创建一个直方图,接受用户输入的bin计数,并用曲线覆盖它以适合分布。绘制的数据是一个人切割cookie所需的时间。
关键功能:
geom_histogram(aes(y = ..count ..),bins = input $ binCount) - 此语句使用用户指定的箱数创建频率图。
geom_density(a =(..density ..)(N)(binWidth))) - 此语句假设以创建适合的曲线分配。 “N”是数据点的总数(20),“binWidth”是每个bin的宽度(默认值= 5),其根据用户指定的bin的数量而变化。可以找到对此转换背后的数学的完整解释here。
问题:“geom_density()”函数中的“aes()”映射语句无法识别先前在“RenderPlot”中创建的变量“N”或“binWidth”块。
代码:以下代码可立即运行。第84行将导致错误。如果您想查看David或Sharon的应该的结果(默认binCount = 5),那么您可以取消注释第85或86行。
类似问题:我发现了一些处理类似ggplot问题的帖子,例如this post,但它们主要处理使用“aes_string()”将字符串传递给映射语句,我正在使用数字变量。
感谢您提供的任何帮助!
#
# Cookie Cutting Analytics
#
# Author: Cody
# Date: 10/16/2017
# Descr: An application to analyze David and Sharon's cookie cutting efficiency.
#
# Libraries -----------------------------------------------------------
suppressWarnings(library(dplyr))
suppressWarnings(library(ggplot2))
suppressWarnings(library(shiny))
# User Interface ------------------------------------------------------
ui <- fluidPage(
# App Title
titlePanel("Cookie Cutting Analytics"),
# Sidebar layout
sidebarLayout(
# Sidebar panel for Input
sidebarPanel(
# Input: Proc Name Dropdown
selectInput("cutterPerson", "Cookie Cutter:",
c("David", "Sharon")),
# Input: Histogram Bin Count Slider
sliderInput("binCount", "Number of Bins:",
min = 1,
max = 10,
value = 5)
),
# Main panel for displaying outputs
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Plots",
br(),
plotOutput("histogram"),
br(),
plotOutput("boxPlot")),
tabPanel("Stats", verbatimTextOutput("summary")),
tabPanel("Data", tableOutput("table"))
)
)
)
)
# Server Logic --------------------------------------------------------
server <- function(input, output) {
# Reactive Expression: Cookie Data
cookieData.df <- reactive ({
person <- c("David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon")
cutTime <- c(5,10,8,12,6,9,8,8,4,15,9,14,5,9,7,12,6,13,8,11,6,12,6,10,8,13,9,8,5,11,4,13,7,10,5,12,6,10,5,15)
data.frame(person, cutTime)
})
# Reactive Expression: Person Cutting
cutterName <- reactive({
input$cutterPerson
})
# Reactive Expression: Filtered Data
filteredData.df <- reactive({
cookieData.df() %>% select(person, cutTime) %>% filter(person == input$cutterPerson)
})
# Output: Histogram
output$histogram <- renderPlot({
N <- nrow(filteredData.df())
binWidth = (max(filteredData.df()$cutTime)-min(filteredData.df()$cutTime) / input$binCount)
ggplot(filteredData.df(), aes(cutTime)) +
geom_histogram(aes(y = ..count..), bins = input$binCount) +
geom_density(aes(y = ..density..* N * binWidth), color = "red") + # Error: Does not recognize "N" or "binWidth"
#geom_density(aes(y = ..density.. * 20 * 1), color = "red") + # David Curve: N = 10, binWidth = (max(cutTime)-min(cutTime))/binCount = (9-4)/5 = 1
#geom_density(aes(y = ..density.. * 20 * 1.4), color = "red") + # Sharon Curve: N = 10, binWidth = (max(cutTime)-min(cutTime))/binCount = (15-8)/5 = 1.4
labs(title = "Histogram of Cookie Cut Times", x = "Cut Duration (s)", y = "Frequency") +
theme(plot.title = element_text(size = 25, face = "bold"),
axis.title = element_text(size = 15, face = "bold"))
})
# Reactive Expression: (N) Filtered Data
N <- reactive({
nrow(filteredData.df())
})
# Reactive Expression: (binWidth) Filtered Data
binWidth <- reactive({
(max(filteredData.df()$cutTime) - min(filteredData.df()$cutTime)) / input$binCount
})
}
shinyApp(ui, server)
答案 0 :(得分:4)
考虑更简单的例子
# works
ggplot(iris, aes(Sepal.Width)) + geom_density(aes(y=..density.. * 5))
# doesn't work
N <- 5
ggplot(iris, aes(Sepal.Width)) + geom_density(aes(y=..density.. * N))
对于为你做计算的ggplot图层,他们需要创建自己的变量,当他们这样做时,他们无法访问他们没有创建的值(至少它是当前实现的方式)。
所以你有两个我能想到的选择:1)自己计算密度,或2)动态构建表达式,使其中没有其他未评估的变量。
对于选项一,可能看起来像
dens <- density(iris$Sepal.Width, kernel = "gaussian") #geom_density equivalent
N <- 5
ggplot(iris, aes(Sepal.Width)) +
geom_histogram() +
geom_area(aes(x, y*N), data=data.frame(x=dens$x, y=dens$y))
对于选项2,您可以这样
N <- 5
dens_map <- eval(bquote(aes(y = ..density..* .(N))))
ggplot(iris, aes(Sepal.Width)) +
geom_histogram() +
geom_density(dens_map)
它基本上将变量名称扩展为它的数值。
答案 1 :(得分:0)
虽然之前的答案已经足够好了,但stat_density
允许我们提取密度值,我们可以在其上创建算术运算并构建图层,只是想分享这种方法。
if(interactive()){
#
# Cookie Cutting Analytics
#
# Author: Cody
# Date: 10/16/2017
# Descr: An application to analyze David and Sharon's cookie cutting efficiency.
#
# Libraries -----------------------------------------------------------
suppressWarnings(library(dplyr))
suppressWarnings(library(ggplot2))
suppressWarnings(library(shiny))
# User Interface ------------------------------------------------------
ui <- fluidPage(
# App Title
titlePanel("Cookie Cutting Analytics"),
# Sidebar layout
sidebarLayout(
# Sidebar panel for Input
sidebarPanel(
# Input: Proc Name Dropdown
selectInput("cutterPerson", "Cookie Cutter:",
c("David", "Sharon")),
# Input: Histogram Bin Count Slider
sliderInput("binCount", "Number of Bins:",
min = 1,
max = 10,
value = 5)
),
# Main panel for displaying outputs
mainPanel(
tabsetPanel(type = "tabs",
tabPanel("Plots",
br(),
plotOutput("histogram"),
br(),
plotOutput("boxPlot")),
tabPanel("Stats", verbatimTextOutput("summary")),
tabPanel("Data", tableOutput("table"))
)
)
)
)
# Server Logic --------------------------------------------------------
server <- function(input, output) {
# Reactive Expression: Cookie Data
cookieData.df <- reactive ({
person <- c("David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon","David","Sharon")
cutTime <- c(5,10,8,12,6,9,8,8,4,15,9,14,5,9,7,12,6,13,8,11,6,12,6,10,8,13,9,8,5,11,4,13,7,10,5,12,6,10,5,15)
data.frame(person, cutTime)
})
# Reactive Expression: Person Cutting
cutterName <- reactive({
input$cutterPerson
})
# Reactive Expression: Filtered Data
filteredData.df <- reactive({
cookieData.df() %>% select(person, cutTime) %>% filter(person == input$cutterPerson)
})
# Output: Histogram
output$histogram <- renderPlot({
#N <- nrow(filteredData.df())
#binWidth = (max(filteredData.df()$cutTime)-min(filteredData.df()$cutTime) / input$binCount)
#N <- 20
#binWidth = 1
n <- ggplot(filteredData.df(), aes(cutTime))
n.data <- ggplot_build (n + stat_density(aes(y =..density..)))[['data']][[1]]
n.data$y <- n.data$y * N() * binWidth()
#n.data$y <- n.data$y * 20 * 1
n + geom_histogram(aes(y = ..count..), bins = input$binCount) +
geom_line(data = n.data, aes(x = x, y = y), color = 'red') +
#geom_density(aes(y = ..density.. * 20 * 1), color = "red") + # David Curve: N = 10, binWidth = (max(cutTime)-min(cutTime))/binCount = (9-4)/5 = 1
#geom_density(aes(y = ..density.. * 20 * 1.4), color = "red") + # Sharon Curve: N = 10, binWidth = (max(cutTime)-min(cutTime))/binCount = (15-8)/5 = 1.4
labs(title = "Histogram of Cookie Cut Times", x = "Cut Duration (s)", y = "Frequency") +
theme(plot.title = element_text(size = 25, face = "bold"),
axis.title = element_text(size = 15, face = "bold"))
#m <- print(m)
})
# Reactive Expression: (N) Filtered Data
N <- reactive({
nrow(filteredData.df())
})
# Reactive Expression: (binWidth) Filtered Data
binWidth <- reactive({
(max(filteredData.df()$cutTime) - min(filteredData.df()$cutTime)) / input$binCount
})
}
shinyApp(ui, server)
}
截图: