How to make one dataframe from a specific item from each response in a list?

I'm having a list of 4 items in R from a spotify API request:

> lijstwijk
[[1]]
Response [https://api.spotify.com/v1/search?q=track%3APompeii%20artist%3ABastille&type=track&limit=1]
  Date: 2020-06-16 20:14
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 2.78 kB
{
  "tracks" : {
    "href" : "https://api.spotify.com/v1/search?query=track%3APompeii+artist%3ABastille&type=track&offset=0&limit=1",
    "items" : [ {
      "album" : {
        "album_type" : "album",
        "artists" : [ {
          "external_urls" : {
            "spotify" : "https://open.spotify.com/artist/7EQ0qTo7fWT7DPxmxtSYEc"
          },
...

[[2]]
Response [https://api.spotify.com/v1/search?q=track%3AUnderdog%20artist%3AAlicia%20Keys&type=track&limit=1]
  Date: 2020-06-16 20:14
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 3.84 kB
{
  "tracks" : {
    "href" : "https://api.spotify.com/v1/search?query=track%3AUnderdog+artist%3AAlicia+Keys&type=track&offset=0&limit=1",
    "items" : [ {
      "album" : {
        "album_type" : "single",
        "artists" : [ {
          "external_urls" : {
            "spotify" : "https://open.spotify.com/artist/3DiDSECUqqY1AuBP8qtaIa"
          },
...

[[3]]
Response [https://api.spotify.com/v1/search?q=track%3AThe%20Way%20It%20Is%20artist%3ABruce%20Hornsby%20&%20The%20Range=&type=track&limit=1]
  Date: 2020-06-16 20:14
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 4.58 kB
{
  "tracks" : {
    "href" : "https://api.spotify.com/v1/search?query=track%3AThe+Way+It+Is+artist%3ABruce+Hornsby+&type=track&offset=0&limit=1",
    "items" : [ {
      "album" : {
        "album_type" : "album",
        "artists" : [ {
          "external_urls" : {
            "spotify" : "https://open.spotify.com/artist/2iM28IgKg89v1o7BTQAVPo"
          },
...

[[4]]
Response [https://api.spotify.com/v1/search?q=track%3ABefore%20You%20Go%20artist%3ALewis%20Capaldi&type=track&limit=1]
  Date: 2020-06-16 20:14
  Status: 200
  Content-Type: application/json; charset=utf-8
  Size: 3.76 kB
{
  "tracks" : {
    "href" : "https://api.spotify.com/v1/search?query=track%3ABefore+You+Go+artist%3ALewis+Capaldi&type=track&offset=0&limit=1",
    "items" : [ {
      "album" : {
        "album_type" : "single",
        "artists" : [ {
          "external_urls" : {
            "spotify" : "https://open.spotify.com/artist/4GNC7GD6oZMSxPGyXy4MNB"
          },

I only need the item spotify:track uri from every response in the list. So for the first two results i did this by hand:

# item one #

> itemone <- lijstwijk[[1]]
> itemoneparsed <- content(itemone, as="parsed")
> uritstone <- itemoneparsed$tracks$items[[1]]$uri
> uritstone 

[1] "spotify:track:3gbBpTdY8lnQwqxNCcf795"

#item two#
> itemtwo <- lijstwijk[[2]]
> itemtwoparsed <- content(itemtwo, as="parsed")
> uritsttwo <- itemtwoparsed$tracks$items[[1]]$uri
> uritsttwo 

[1] "spotify:track:3FGiFUJRRp5RGikVrs6kig"

How to make a dataframe containing the item spotify:track: from each response in the list?

How can i make one dataframe containing the item spotify:track: from each response of the list? As example:

Spotifytrackuri
1. "spotify:track:3gbBpTdY8lnQwqxNCcf795"
2. "spotify:track:3FGiFUJRRp5RGikVrs6kig"
3. "spotify:track:xxxxxxxxxxxxxxxxxxxxxx"
4. "spotify:track:xxxxxxxxxxxxxxxxxxxxxx"

Please note that for this example i have 4 responses. But there will be more. For each response , therefore, the item spotify: track: must be removed from the response and placed in one data frame.

How can i archieve this result? I've tried the lapply function but i'm getting a subscript out of bound error:

> lijstwijkuri <- lapply(lijstwijk, function(item) content(item, as="parsed")$tracks$items[[1]]$uri)
Error in content(item, as = "parsed")$tracks$items[[1]] : 
  subscript out of bounds

I think lapply should work. How about if you make a named function?

myfunc <- function(item){
  content(item, as="parsed")$tracks$items[[1]]$uri
}
lijstwijkuri <- lapply(lijstwijk, myfunc)
1 Like

it's not working. I'm getting the error "subscript out of bounds" again.

> myfunc <- function(item){
+   content(item, as="parsed")$tracks$items[[1]]$uri
+ }
> lijstwijkuri <- lapply(lijstwijk, myfunc)
Error in content(item, as = "parsed")$tracks$items[[1]] : 
  subscript out of bounds

Here is my script:

#Get playlist url #
url <- "https://www.nporadio2.nl/playlist"

#Read HTML code from pagen#
webpage <- read_html(url)

#Get Artist and Title#
artist <- html_nodes(webpage, '.fn-artist')
title <- html_nodes(webpage, '.fn-song')

#Artist and Title to text#
artist_text <- html_text(artist)
title_text <- html_text(title)

#Artist and Title to dataframe#
artiest <- as.data.frame(artist_text)
titel_text <- as.data.frame(title_text)

#Make one dataframe#
radioplaylist <- cbind(artiest$artist_text, titel_text$title_text)
radioplaylist <- as.data.frame(radioplaylist) 
radioplaylist

#Rename columns#
colnames(radioplaylist)[1] <- "Artiest"
colnames(radioplaylist)[2] <- "Titel"
radioplaylist

#Remove duplicate songs#
radioplaylistuniek <- radioplaylist %>% distinct(Artiest, Titel, .keep_all = TRUE)

#Set spotify API#
Sys.setenv(SPOTIFY_CLIENT_ID = 'xxxxxxxxxxxxxxxxxxxx')
Sys.setenv(SPOTIFY_CLIENT_SECRET = 'xxxxxxxxxxxxx')
access_token <- get_spotify_access_token()

# Client and secret#
clientID <- "xxxxxxxxxxxxxxx"
secret <- "xxxxxxxxxxxxxxxxx"

# Get access token and write this to authorization header #
response = POST(
  'https://accounts.spotify.com/api/token',
  accept_json(),
  authenticate(clientID, secret),
  body = list(grant_type = 'client_credentials'),
  encode = 'form',
  verbose()
)

token = content(response)$access_token
authorization.header = paste0("Bearer ", token)

# Generate URLS #
radioplaylistuniektest <- radioplaylistuniek[1:100,]
urls <- list(c("https://api.spotify.com/v1/search?q=track:")) %>% paste0(radioplaylistuniektest$Titel) %>% paste0(c("%20artist:")) %>% paste0(radioplaylistuniektest$Artiest) %>% paste(c("&type=track&limit=1"), sep = "")

# Get track information#
lijstwijk <- lapply(urls, GET, simplifyMatrix=TRUE, flatten=TRUE, config = add_headers(authorization = authorization.header))

# Get trackuri from each response#
lijstwijkuri <- lapply(lijstwijk, function(item) content(item, as="parsed")$tracks$items[[1]]$uri)

assuming its small with only 4 entries, can you do

dput(lijstwijk)

to share the object to the forum, so that we can test the code against it ?

Got the solution. So for anyone who is curious. This is how i fixed it:

# Unlist results #
responses <- unlist(lapply(lijstwijk, paste, collapse=" "))

# Results to dataframe #
responsesdf <- as.data.frame(responses)

# Get spotify:track string#
uriperurl <- data.frame(uri = str_extract(responsesdf$responses, "(spotify:track:)\\w+"))
1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.