How can I use a slider in R Shiny to control the frequency by which a category is sampled? - shiny

I want to use a slider in R Shiny to give the user control over the frequency a category is sampled from a data frame. The slider should have a default value of 0.5 (and range from 0 to 1), and at the default value (0.5), I have defined the frequency by which each category should be sampled. When the user adjusts the slider towards 1 (the maximum), I would like the frequencies of the highest categories to become even higher at the expense of the lowest frequency categories and vice-versa when the slider is adjusted towards 0 (the lowest frequency categories should increase, while the highest decrease). The frequencies should always sum to 1.
For example, I have a data frame that contains six categories and the frequencies by which each category is initially sampled. For instance:
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
When the R Shiny slider is set to 1, I want the frequency of the initial highest category (chicken) to be 1.0, with the other categories being 0. As the slider goes to 1, I also want the next highest categories (beef and fish) to increase, but they should maintain the initial frequency order (with chicken remaining highest) until (as the slider gets closer to 1) they also go to 0 and chicken goes to 1.0. The highest categories (chicken, beef, and fish) should grow at the expense of the lowest categories (tofu, lamb, and shrimp), with shrimp (the lowest frequency) being the first to go to 0, followed by lamb and tofu.
I would like a similar (but opposite) process to occur as the slider goes to 0, with shrimp eventually being at a frequency of 1 (and lamb and tofu initially increasing at the expense of the higher frequency categories) and chicken being the first to go to 0 (followed by beef, fish, tofu, and lamb).
Essentially I need to rework the sample_data function in the example below:
library(shiny)
sample_data <- function(slider_value, data) {
adjusted_frequency <- data$frequency + (slider_value) * (max(data$frequency) - data$frequency)
data$sampled_frequency <- adjusted_frequency / sum(adjusted_frequency)
return(data)
}
ui <- fluidPage(
titlePanel("Input Data Using a Slider"),
sidebarLayout(
sidebarPanel(
sliderInput("value", "Enter a value:",
min = 0, max = 1, value = 0.5)
),
mainPanel(
tableOutput("data")
)
)
)
server <- function(input, output) {
df <- data.frame(food = c("fish", "shrimp", "chicken", "lamb", "beef", "tofu"), frequency = c(0.20, 0.06, 0.30, 0.10, 0.23, 0.11))
data <- reactive({
sample_data(input$value, df)
})
output$data <- renderTable({
data()
})
}
shinyApp(ui, server)
Right now, the slider I have gives the results as depicted in the image below:
When set to 0, it displays the default frequencies, and when set to 1 it has all categories at equal frequencies. How can I improve the sample_data function to accomplish the more complicated procedure I have described?
Thank you very much for your help!

Related

Pinescript. Plotting conditional statement

If the variable barup is true, I want it to plot one series; if the variable bardown is true, I want it to plot another series value.
My current code yields the error: Cannot use "plot in local scope".
How do I change the following code to make the indicator show the number of days the lows have been above the 30 ema or below the 30 day ema based on the high or low of the current day.
Here is the code I have now:
indicator("LandryLight")
bardown = high < ta.ema(close,30)
barup = low > ta.ema(close,30)
if barup
plot(series=ta.barssince(barup)*-1, title="Consecutive Bars Down", color=color.red, style=plot.style_histogram, linewidth=2)
if bardown
plot(series=ta.barssince(bardown), title="Consecutive Bars Up", color=color.green, style=plot.style_histogram, linewidth=2)
hline(10,title="Threshold", color=color.white, linestyle=hline.style_dashed, linewidth=1)
First Use tag [pine-script]
Try going step by step, and then the plot
I would do it like this:
//#version=5
indicator("LandryLight")
bardown = high < ta.ema(close,30)
barup = low > ta.ema(close,30)
barupCont = ta.barssince(barup)*-1
bardownCont = ta.barssince(bardown)
barupOK = barup ? barupCont : na
bardownOK = bardown ? bardownCont : na
plot(series= barupOK, title="Consecutive Bars Down", color=color.red, style=plot.style_histogram, linewidth=2)
plot(series= bardownOK, title="Consecutive Bars Up", color=color.green, style=plot.style_histogram, linewidth=2)
hline(10,title="Threshold", color=color.white, linestyle=hline.style_dashed, linewidth=1)

Need some help writing a "centripetal force" app for physics class

I'm fairly new to rshiny. I'm sure my problem is addressed in various documentation, but I'm not finding it.
The centripetal force (physics) depends on mass, velocity, and radius. I want the students to play with all three to see what happens to the force. I'm using sliders for the variables.
But I also want them to explore the relationship between velocity and radius when the force is fixed. For that, I use a checkbox and I try to catch whether the radius slider was moved (in which case update the velocity slider such that the force is fixed) or whether the velocity slider was moved (in which case update the radius slider keeping the force fixed).
This has caused some undesired behavior - moving one slider does update the other slider, but they keep updating and eventually end up all the way to the left, or all the way to the right.
I think when moving all three sliders I want the force output to be reactive, but when the checkbox is checked I don't want the force output to be reactive. I want it fixed.
I could use some help or hints. Here is my code:
library(shiny)
# Define UI for application that explores centripetal acceleration
update_svg <- function(radius, velocity) {
svg <- paste(readLines("images/centripetal-animated.svg"), collapse = "\n")
# transformations ...
scale <- round(radius/40, 4)
dt <- round(2*pi*radius/velocity, 2)
dy <- round(-36*velocity/62.83/scale, 4)
a <- velocity^2/radius
dx <- round(-52.92*a/100/scale, 4)
x0 <- 148.166664 + dx
cx <- round((scale - 1)*95.25, 2)
cy <- round((scale - 1)*100.54166, 2)
svg <- sub("\\{scale\\}", scale, svg)
svg <- sub("\\{DY\\}", dy, svg)
svg <- sub("\\{X0\\}", x0, svg)
svg <- sub("\\{DX\\}", -dx, svg)
svg <- sub("\\{DT\\}", dt, svg)
svg <- sub("\\{CX\\}", -cx, svg)
svg <- sub("\\{CY\\}", -cy, svg)
con <- paste0(tempfile("svg"), ".svg")
writeLines(svg, con)
con
}
ui <- fluidPage(
# Application title
titlePanel("Physics"),
# Tabset panel
tabsetPanel(
tabPanel("Centripetal Acceleration",
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
sliderInput("mass",
"Mass (kg):",
min = 0,
max = 10,
value = 5),
sliderInput("radius",
"Radius (m):",
min = 0,
max = 60,
value = 30),
sliderInput("velocity",
"Tangential Velocity (m/s):",
min = 0,
max = 60,
value = 30),
textOutput("angular"),
textOutput("acceleration"),
list(textInput("force", "Force (N):", 150), checkboxInput("freeze", "Fix mass & force"))
),
# Show a plot of the generated distribution
mainPanel(
imageOutput("svg")
)
)
)
)
)
# Define server logic
server <- function(input, output, session) {
# if force is fixed, observe change in radius and adjust
# velocity to maintain fixed acceleration and force.
observeEvent(input$radius, {
if (input$freeze == 1) {
updateSliderInput(session = session, inputId = "velocity",
value = sqrt(as.numeric(input$force)*input$radius/input$mass))
}
})
# if force is fixed, observe change in velocity and
# adjust radius to maintain fixed acceleration and force.
observeEvent(input$velocity, {
if (input$freeze == 1) {
updateSliderInput(session = session, inputId = "radius",
value = input$mass*input$velocity^2/as.numeric(input$force))
}
})
observe({
angular <- input$velocity/input$radius
acceleration <- input$radius*angular^2
force <- input$mass*acceleration
output$angular <- renderText(paste0("Angular Velocity: ", signif(angular, 2), " (rad/s)"))
output$acceleration <- renderText(paste0("Acceleration: ", signif(acceleration, 2), " (m/s^2)"))
updateTextInput(session ,"force", value = signif(force, 2))
output$svg <- renderImage(list(src = update_svg(input$radius, input$velocity)))
})
}
# Run the application
shinyApp(ui = ui, server = server)

Shiny - dygraphs: Show all error-bar values in legend

I am using dygraphs for R and I opened the following issue on GitHub the other day, however, I have not yet received an answer. Therefore, I am hoping someone in here will be able to answer my question.
I want to know if it is possible to show all the values of the prediction interval in the legend, i.e. , lower, actual, upper, without having them as three separate plain dySeries? I like the look of the shading that the upper/lower bars bring, but I would also like to be able to hover over a point and see all the values for that particular point, not just the middle one. If such a function does not exists, is there an easy workaround, maybe with fillGraph = TRUE or something?
library(dygraphs)
hw <- HoltWinters(ldeaths)
p <- predict(hw, n.ahead = 72, prediction.interval = TRUE)
dygraph(p, main = "Predicted Lung Deaths (UK)") %>%
dySeries(c("lwr", "fit", "upr"), label = "Deaths")
The preceding code is the example from the web page, which is similar to my problem. I simply want to see the lwr and upr values in the legend when hovering.
So I found a workaround for anybody looking for something similar.
library(dygraphs)
hw <- HoltWinters(ldeaths)
p <- predict(hw, n.ahead = 72, prediction.interval = TRUE)
max <- p[,2]
min <- p[,3]
p <- ts.union(p, max, min)
dygraph(p, main = "Predicted Lung Deaths (UK)") %>%
dySeries(c("p.lwr", "p.fit", "p.upr"), label = "Deaths") %>%
dySeries("max", label = "Max", pointSize = 0.01, strokeWidth = 0.001) %>%
dySeries("min", label = "Max", pointSize = 0.01, strokeWidth = 0.001)
Obviously, this can be modified to suit your needs (e.g. color of the points etc.) The main idea in this method is simply to create two new columns containing the same information that is used in the bands, and then to make the lines to these too small to see.

Creating standard error bars in lattice xyplot graphs with multiple panels

I have a dataset in which I am graphing means from 4 treatments over time, along with their standard errors, at 2 sites. The standard error bars are not being assigned properly to their respective means --they are going to both panels - can you please advise? See example:
d <- data.frame(site=rep(1:2,each=12),time=rep(1:3,8),trt=rep(rep(1:4,each=3),2))
d$mn <- rnorm(24,4,1)
d$se <- rnorm(24,2,1)
d$ul <- d$mn+d$se # create y value for standard error upper limit
my.panel <- function(x,y, ...){
panel.xyplot(x, y, ...)
panel.arrows(x, y, x, d$ul, length = 0.1,
angle = 90)
}
xyplot(mn ~ time|site,data=d,
group = trt,
type=c('p','l'),
panel = my.panel
)

What causes markers' locations to be inaccurate (by ~500 m) in shiny-leaflet map?

I am trying to create a leaflet map as part of an R-Shiny project which displays circle markers at locations I previously geocoded from address information using the Google API. Putting the lon/lat values back into Google gives me the exact location of the address.
When I create the map from those lon/lat values in my shiny project using the code below, the marker positions are off in random directions by a few 100 meters (at maximum zoom level).
Based on google searches my guess is that it is something to do with markers changing position due to zoom level or with incompatible map projections.
output$mymap <- renderLeaflet({
alldata_sel = alldata
if(input$dachverbandCheck != T){alldata_sel = filter(alldata_sel, Dachverband==input$dachverband)}
if(input$landkreisCheck != T){alldata_sel = filter(alldata_sel, Landkreis==input$landkreis)}
if(input$leistungstypCheck != T){alldata_sel = filter(alldata_sel,
LeistungstypBezeichnung==input$leistungstyp)}
if(input$traegerCheck != T){alldata_sel = filter(alldata_sel, Traegername==input$traeger)}
#initialize map and setView
leaflet(options = leafletOptions(minZoom = 5, maxZoom = 18)) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
data = alldata_sel,
lng=~longitude, # Longitude coordinates
lat=~latitude, # Latitude coordinates
radius=~KapRadius,
stroke=FALSE, # Circle stroke
fillOpacity=0.5, # Circle Fill Opacity
color = rgb(alldata_sel$colour_r, alldata_sel$colour_g, alldata_sel$colour_b,
maxColorValue = 255)
)
})