我正在使用Spotify的API创建一个闪亮的应用程序:
1)您手动输入艺术家姓名
2)在selectInput中,相册需要自动填充以供选择。
3)选择相册后,主面板中的表格将显示歌曲,艺术家和专辑。
到目前为止,我有这个工作,但我无法弄清楚如何选择艺术家后第二部分自动填充相册。我在这里问了一个上一个问题:Shiny: Automatic SelectInput Value Update Based on Previous Filter但我意识到在提问之后,数据集在开头就不会被你知道了。
所以不要这样做:
selectInput("selectinputid", "Album #1 to Select:", choices = c("Yeezus" = "Yeezus", "Graduation" = "Graduation", "Gears" = "gear"))
我想这样做:
selectInput("selectinputid", "Album #1 to Select:", choices = unique(with_album_name$`Album Name`)
以下是代码:
# ui.R
library(shiny)
shinyUI(fluidPage(
titlePanel("Spotify: Interactive Song Selection"),
sidebarLayout(
sidebarPanel(
helpText("The goal from this is for you to compare two artists' albums and see how similar the songs are based on the audio features."),
helpText("Select your first artist you want to compare. For example: ",
tags$b("Kanye West")),
textInput("albumId", "Artist Name #1", value = "", width = NULL,
placeholder = NULL),
actionButton("goButton", "Submit Both Artists"),
helpText("Based on the artist you selected, now select the albums that you want to compare songs for."),
selectInput("selectinputid", "Album #1 to Select:", choices = c("Yeezus" = "Yeezus", "Graduation" = "Graduation", "Gears" = "gear")),
actionButton("goButton1", "Submit Both Albums")),
mainPanel(
tableOutput("result")
)
)
))
服务器部分:
# server.R
spotifyKey <- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
spotifySecret <- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
library("httr")
library("jsonlite")
library(ggplot2)
library(scales)
library(dplyr)
response = POST(
'https://accounts.spotify.com/api/token',
accept_json(),
authenticate(spotifyKey, spotifySecret),
body = list(grant_type = 'client_credentials'),
encode = 'form',
verbose()
)
token = content(response)$access_token
HeaderValue = paste0('Bearer ', token)
library(shiny)
shinyServer(function(input, output) {
output$result <- renderTable({
randomVals <- eventReactive(input$goButton, input$albumId)
spotify <- c(randomVals())
##Retrieve Artist ID
get.artist <- function(spotify){
artistnameURL <- paste("https://api.spotify.com/v1/search?q=", spotify, "&type=artist", sep="")
getArtist <- GET(artistnameURL, add_headers(Authorization = HeaderValue))
artistname <- jsonlite::fromJSON(toJSON(content(getArtist)))
ids <- data.frame(matrix(unlist(artistname$artists$items$id),
nrow=artistname$artists$total,
byrow=T),stringsAsFactors=FALSE)
names <- data.frame(matrix(unlist(artistname$artists$items$name),
nrow=artistname$artists$total,
byrow=T),stringsAsFactors=FALSE)
colnames(ids)[1]<-"Artist ID"
colnames(names)[1]<-"Artist Name"
artist_search <- cbind(names, ids)
artist_search <- artist_search[1,]
return(artist_search)
}
df1 <- lapply(spotify, get.artist)
result2 <- do.call(rbind, df1)
result2_final<-result2
ids<-result2_final$`Artist ID`
##Retrieve Artist Albums
get.albums <- function(ids){
artists_albumsURL <- paste("https://api.spotify.com/v1/artists/", ids, "/albums", sep="")
getArtistAlbum <- GET(artists_albumsURL, add_headers(Authorization = HeaderValue))
artistalbumname <- jsonlite::fromJSON(toJSON(content(getArtistAlbum)))
albumids <- data.frame(matrix(unlist(artistalbumname$items$id),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
albumnames <- data.frame(matrix(unlist(artistalbumname$items$name),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
artistid2 <- data.frame(matrix(unlist(artistalbumname$items$artists[[1]]$id),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
artistname2 <-
data.frame(matrix(unlist(artistalbumname$items$artists[[1]]$name),
nrow=artistalbumname$total, byrow=T),stringsAsFactors=FALSE)
colnames(albumids)[1]<-"Album IDs"
colnames(albumnames)[1]<-"Album Name"
colnames(artistid2)[1]<-"Artist ID"
colnames(artistname2[1])<-"Artist Name"
album_search <- cbind(artistid2, artistname2, albumnames, albumids)
album_search <- unique(album_search)
return(album_search)
}
df <- lapply(ids, get.albums)
result <- do.call(rbind, df)
result_final<-result
colnames(result_final)[2]<-"Artist Name"
spotify<-result_final$`Album IDs`
get.tracks <- function(spotify){
albumTracksURL <- paste("https://api.spotify.com/v1/albums/", spotify, "/tracks?limit=50", sep="")
getTracks <- GET(albumTracksURL, add_headers(Authorization = HeaderValue))
albumTracks <- jsonlite::fromJSON(toJSON(content(getTracks)))
ids <- data.frame(matrix(unlist(albumTracks$items$id),
nrow=albumTracks$total, byrow=T),stringsAsFactors=FALSE)
names <- data.frame(matrix(unlist(albumTracks$items$name),
nrow=albumTracks$total, byrow=T),stringsAsFactors=FALSE)
artists<-albumTracks$items$artists
artists1<-do.call(rbind, lapply(artists, function(x) do.call(cbind, lapply(x[c('id', 'name')], toString))))
result <- cbind(ids, names, artists1)
colnames(result) <- c("ID", "NAME", "ARTIST ID", "ARTIST NAME")
result$AlbumID <- spotify
return(result)
}
df <- lapply(spotify, get.tracks)
result <- do.call(rbind, df)
result_final2<-result
names(result_final2) <- c("ID", "NAME", "ARTIST ID", "ARTIST NAME")
final<-result_final2
final1<-final[!duplicated(final), ]
final2 <- final1[!duplicated(final1[2:5]),]
colnames(final2)[5]<-"Album ID"
with_album_name<-left_join(final2,result_final, by=c("Album ID" = "Album IDs"))
with_album_name <- with_album_name[,-c(6:7)]
##target <- c(input$selectinputid)
randomVals2 <- eventReactive(input$goButton1, input$selectinputid)
target <- c(randomVals2())
result_final<-filter(with_album_name, `Album Name` %in% target)
final2<-result_final
final2
})})
输出:
在ui部分,我需要找到一种引用with_album_name
表的方法,但该表是在服务器部分创建的。不知道如何做到这一点,因为现在我只需要手动输入相册名称进行选择,当我想在spotify数据库中引用不同的艺术家时,这将无效。
答案 0 :(得分:1)
我覆盖了你的服务器部分:
将所有功能移出它(我更喜欢将我的服务器功能保存在一个单独的文件中);
重组服务器代码:所有代码都返回单个表。我现在已将observeEvent
添加到更新列表
selectInput
部分的细微变化:
selectInput("selectinputid", "Album #1 to Select:", "")
服务器部分:
server <- function(input, output, session) {
ids <- reactive({
randomVals <- eventReactive(input$goButton, input$albumId)
spotify <- c(randomVals())
df1 <- lapply(spotify, get.artist)
result2 <- do.call(rbind, df1)
result2_final<-result2
result2_final$`Artist ID`
})
result_final <- reactive({
df <- lapply(ids(), get.albums)
result <- do.call(rbind, df)
colnames(result)[2]<-"Artist Name"
result
})
# Observes and updates album selection part
observe({
albums <- unique(result_final()$`Album Name`)
updateSelectInput(session, "selectinputid",
label = "selectinputid",
choices = albums,
selected = albums[1])
})
output$result <- renderTable({
spotify<-result_final()$`Album IDs`
df <- lapply(spotify, get.tracks)
result <- do.call(rbind, df)
result_final2<-result
names(result_final2) <- c("ID", "NAME", "ARTIST ID", "ARTIST NAME")
final<-result_final2
final1<-final[!duplicated(final), ]
final2 <- final1[!duplicated(final1[2:5]),]
colnames(final2)[5]<-"Album ID"
with_album_name<-left_join(final2,result_final(), by=c("Album ID" = "Album IDs"))
with_album_name <- with_album_name[,-c(6:7)]
randomVals2 <- eventReactive(input$goButton1, input$selectinputid)
target <- c(randomVals2())
result_final<-filter(with_album_name, `Album Name` %in% target)
final2<-result_final
final2
})
}
所有代码(凌乱):
library(shiny)
ui <- fluidPage(
titlePanel("Spotify: Interactive Song Selection"),
sidebarLayout(
sidebarPanel(
helpText("The goal from this is for you to compare two artists' albums and see how similar the songs are based on the audio features."),
helpText("Select your first artist you want to compare. For example: ",
tags$b("Kanye West")),
textInput("albumId", "Artist Name #1", value = "", width = NULL,
placeholder = NULL),
actionButton("goButton", "Submit Both Artists"),
helpText("Based on the artist you selected, now select the albums that you want to compare songs for."),
selectInput("selectinputid", "Album #1 to Select:", ""),
actionButton("goButton1", "Submit Both Albums")),
mainPanel(
tableOutput("result")
)
)
)
spotifyKey <- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
spotifySecret <- "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
library("httr")
library("jsonlite")
library(ggplot2)
library(scales)
library(dplyr)
response = POST(
'https://accounts.spotify.com/api/token',
accept_json(),
authenticate(spotifyKey, spotifySecret),
body = list(grant_type = 'client_credentials'),
encode = 'form',
verbose()
)
token = content(response)$access_token
HeaderValue = paste0('Bearer ', token)
get.artist <- function(spotify){
artistnameURL <- paste("https://api.spotify.com/v1/search?q=", spotify, "&type=artist", sep="")
getArtist <- GET(artistnameURL, add_headers(Authorization = HeaderValue))
artistname <- jsonlite::fromJSON(toJSON(content(getArtist)))
ids <- data.frame(matrix(unlist(artistname$artists$items$id),
nrow=artistname$artists$total,
byrow=T),stringsAsFactors=FALSE)
names <- data.frame(matrix(unlist(artistname$artists$items$name),
nrow=artistname$artists$total,
byrow=T),stringsAsFactors=FALSE)
colnames(ids)[1]<-"Artist ID"
colnames(names)[1]<-"Artist Name"
artist_search <- cbind(names, ids)
artist_search <- artist_search[1,]
return(artist_search)
}
get.albums <- function(ids){
artists_albumsURL <- paste("https://api.spotify.com/v1/artists/", ids, "/albums", sep="")
getArtistAlbum <- GET(artists_albumsURL, add_headers(Authorization = HeaderValue))
artistalbumname <- jsonlite::fromJSON(toJSON(content(getArtistAlbum)))
albumids <- data.frame(matrix(unlist(artistalbumname$items$id),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
albumnames <- data.frame(matrix(unlist(artistalbumname$items$name),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
artistid2 <- data.frame(matrix(unlist(artistalbumname$items$artists[[1]]$id),
nrow=artistalbumname$total,
byrow=T),stringsAsFactors=FALSE)
artistname2 <-
data.frame(matrix(unlist(artistalbumname$items$artists[[1]]$name),
nrow=artistalbumname$total, byrow=T),stringsAsFactors=FALSE)
colnames(albumids)[1]<-"Album IDs"
colnames(albumnames)[1]<-"Album Name"
colnames(artistid2)[1]<-"Artist ID"
colnames(artistname2[1])<-"Artist Name"
album_search <- cbind(artistid2, artistname2, albumnames, albumids)
album_search <- unique(album_search)
return(album_search)
}
get.tracks <- function(spotify){
albumTracksURL <- paste("https://api.spotify.com/v1/albums/", spotify, "/tracks?limit=50", sep="")
getTracks <- GET(albumTracksURL, add_headers(Authorization = HeaderValue))
albumTracks <- jsonlite::fromJSON(toJSON(content(getTracks)))
ids <- data.frame(matrix(unlist(albumTracks$items$id),
nrow=albumTracks$total, byrow=T),stringsAsFactors=FALSE)
names <- data.frame(matrix(unlist(albumTracks$items$name),
nrow=albumTracks$total, byrow=T),stringsAsFactors=FALSE)
artists<-albumTracks$items$artists
artists1<-do.call(rbind, lapply(artists, function(x) do.call(cbind, lapply(x[c('id', 'name')], toString))))
result <- cbind(ids, names, artists1)
colnames(result) <- c("ID", "NAME", "ARTIST ID", "ARTIST NAME")
result$AlbumID <- spotify
return(result)
}
server <- function(input, output, session) {
ids <- reactive({
randomVals <- eventReactive(input$goButton, input$albumId)
spotify <- c(randomVals())
df1 <- lapply(spotify, get.artist)
result2 <- do.call(rbind, df1)
result2_final<-result2
result2_final$`Artist ID`
})
result_final <- reactive({
df <- lapply(ids(), get.albums)
result <- do.call(rbind, df)
colnames(result)[2]<-"Artist Name"
result
})
# Observes and updates album selection part
observe({
albums <- unique(result_final()$`Album Name`)
updateSelectInput(session, "selectinputid",
label = "selectinputid",
choices = albums,
selected = albums[1])
})
output$result <- renderTable({
spotify<-result_final()$`Album IDs`
df <- lapply(spotify, get.tracks)
result <- do.call(rbind, df)
result_final2<-result
names(result_final2) <- c("ID", "NAME", "ARTIST ID", "ARTIST NAME")
final<-result_final2
final1<-final[!duplicated(final), ]
final2 <- final1[!duplicated(final1[2:5]),]
colnames(final2)[5]<-"Album ID"
with_album_name<-left_join(final2,result_final(), by=c("Album ID" = "Album IDs"))
with_album_name <- with_album_name[,-c(6:7)]
randomVals2 <- eventReactive(input$goButton1, input$selectinputid)
target <- c(randomVals2())
result_final<-filter(with_album_name, `Album Name` %in% target)
final2<-result_final
final2
})
}
shinyApp(ui, server)