我正在尝试创建一个闪亮的应用程序,该应用程序最多显示2条不同的彩色线条,具体取决于用户选择查看的颜色。但是,我一直收到“意外字符”错误。
我认为问题出在以下代码的selectInput(inputId = "z", label = "Source", choices = c("social_media", "google_ads"), selected = c("social_media", "google_ads"), multiple = TRUE)
行中,因为当我将choices
和selected
替换为source
时,图形似乎可以正常工作(尽管不允许用户选择和查看其他选项。
df是一个看起来像这样的数据框:
av_purchase_count days_since_first_use source
2 1 social_media
5 2 social_media
4 1 google_ads
6 2 google_ads
...这是我尝试过的代码:
library(shiny)
library(ggplot2)
df <- read_xlsx("~/df.xlsx")
ui <- fluidPage(
titlePanel("df"),
sidebarLayout(
sidebarPanel(
selectInput(inputId = "x", label = "Days since first use", choices = "days_since_first_use", selected = "days_since_first_use"),
selectInput(inputId = "y", label = "Average Purchase Count", choices = "av_purchase_count", selected = "av_purchase_count"),
selectInput(inputId = "z", label = "Source", choices = c("social_media", "google_ads"), selected = c("social_media", "google_ads"), multiple = TRUE)
),
mainPanel(
plotOutput("scatterplot")
)
)
)
server <- function(input, output) {
output$scatterplot <- renderPlot({
# generate bins based on input$bins from ui.R
ggplot(data = df, aes_string(x = input$x, y = input$y, colour = input$z)) +
geom_point()
})
}
shinyApp(ui = ui, server = server)
我希望最终图形允许用户选择是否要查看google_ads
,social_media
或两者(默认情况下都是)的结果。
非常感谢,希望这有道理。
答案 0 :(得分:1)
您可以通过实现
class SomeButton: UIButton {
var titleFont: UIFont! = nil
var textSize: CGFloat = 0
let imageWidth: CGFloat = 20
let buttonHeight: CGFloat = 30
override init(frame: CGRect) {
super.init(frame: frame)
self.titleFont = titleLabel!.font
self.setTitle("here", for: .normal)
self.setTitleColor(UIColor.red, for: .normal)
self.setImage(UIImage(named: "hand"), for: .normal)
self.backgroundColor = UIColor.green
}
override func titleRect(forContentRect contentRect: CGRect) -> CGRect {
if let string = self.title(for: .normal) {
textSize = string.widthOfString(usingFont: self.titleFont)
//30 because imageWidth + 10 padding
return CGRect(origin: CGPoint(x: 30, y: 0), size: CGSize(width: textSize + 30, height: buttonHeight))
}
return CGRect.zero
}
override func imageRect(forContentRect contentRect: CGRect) -> CGRect {
return CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: imageWidth, height: buttonHeight))
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override var intrinsicContentSize: CGSize {
//60 because you need eauql padding on both side 30 + 30 = 60
return CGSize(width: textSize + 60, height: buttonHeight)
}
}
extension String {
func widthOfString(usingFont font: UIFont) -> CGFloat {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = self.size(withAttributes: fontAttributes)
return size.width
}
}
变量output$scatterplot <- renderPlot({
ggplot(
data = df %>% filter(source %in% input$z),
aes_string(x = input$x, y = input$y)
) + geom_point(aes(colour = source))
})
反映了用户选择显示的内容(google_ads或social_media或两者)。它是一个反应性矢量,每次更改时都会触发绘图重绘。每次更改时,都对数据框进行过滤,以仅保留用户希望通过input$z
查看的内容。需要注意的另一件事是基于“源”为点着色,您需要使用df %>% filter(source %in% input$z)
而不是aes(color = source)
,因为您不想将源评估为变量。
请记住要安装和加载库(tidyverse),ggplot2也是tidyverse的一部分,因此您可以将aes_string
替换为library(ggplot2)
。如果您真的不想使用tidyverse,则只需使用library(tidyverse)
来过滤数据