【发布时间】:2018-03-03 07:30:34
【问题描述】:
我正在创建一个闪亮的应用程序,它将使用 Spotify 的 API 执行以下操作:
1) 您手动输入艺术家姓名
2) 在 selectInput 中,相册需要自动填充以供您选择。
3) 选择专辑后,主面板中的表格将显示歌曲、艺术家和专辑。
到目前为止,我已经完成了这项工作,但我不知道如何进行第二部分,即在选择艺术家后自动填充专辑。我在这里问了一个之前的问题:Shiny: Automatic SelectInput Value Update Based on Previous Filter 但我意识到,问了这个问题后,数据集一开始是不知道的,供您在 ui 中引用。
所以不要这样做:
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 数据库中引用其他艺术家时,这将不起作用。
【问题讨论】:
-
你问如何更新
output$result? -
不,我在问如何更新 selectInput 选项卡:“Album #1 to Select:” 目前,我正在手动输入“Yeezus”、“Graduation”等,但我想要这个动态更改为手动输入的艺术家的所有可用专辑
标签: r shiny shiny-server