{"id":372,"date":"2020-02-10T21:00:41","date_gmt":"2020-02-10T21:00:41","guid":{"rendered":"https:\/\/eipsoftware.com\/musings\/?p=372"},"modified":"2021-10-03T21:11:15","modified_gmt":"2021-10-03T21:11:15","slug":"lyrical-success-preparing-the-data","status":"publish","type":"post","link":"https:\/\/eipsoftware.com\/musings\/lyrical-success-preparing-the-data\/","title":{"rendered":"Lyrical Success &#8211; Preparing the Data"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">The data created in the previous step needs a little bit of cleaning up before we can get into the model building.  It is a common step that needs to be undertaken to ensure that the data can be loaded into models without any issues.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Part 3 of 4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Steps for Preparing the Data<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><a href=\"#clean_rankings\">Clean the Rankings<\/a><\/li><li><a href=\"#match_song_ranks\" data-type=\"internal\" data-id=\"#match_song_ranks\">Match the Song Ranks<\/a><\/li><\/ol>\n\n\n\n<!--more-->\n\n\n\n<h2 class=\"wp-block-heading\" id=\"clean_rankings\"><strong>Step 1 \u2013 Clean the Rankings<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The first step is to clean up the rankings files that I created in the previous step.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1.01 <\/strong>Load the Packages<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Reference the necessary packages. Proto, gsubfn, magrittr, dplyr, and lubridate.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# clean up the ranking files and merge with the lyrics files\n# ----------------------------------------------------------------------------\nlibrary(proto ,quietly = TRUE, warn.conflicts = FALSE) #used by gsubfn\nlibrary(gsubfn ,quietly = TRUE, warn.conflicts = FALSE)\n\nlibrary(magrittr ,quietly = TRUE, warn.conflicts = FALSE)\nlibrary(dplyr ,quietly = TRUE, warn.conflicts = FALSE)\n\nlibrary(lubridate ,quietly = TRUE, warn.conflicts = FALSE)<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1.02 <\/strong>Load the Ranking Data into Data Frames<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Will use the standard library to read the flat files, and then store the data into a data frame.  All of the flat files have the same number of columns and the column order is identical for each file, no need to reorganize or make adjustments afterwards.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Additionally because I created the ranking files in the prior step, I know that there are no null values.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># load the ranking data\ndf_rankings_drake &lt;- read.delim(paste0(getwd(), \"\/ranks\/Drake.txt\")\n                                    , header = TRUE\n                                    , stringsAsFactors = FALSE\n                             )\n\ndf_rankings_onedirection &lt;- read.delim(paste0(getwd(), \"\/ranks\/One-Direction.txt\")\n                                      , header = TRUE\n                                      , stringsAsFactors = FALSE\n                            )\n\ndf_rankings_pink &lt;- read.delim(paste0(getwd(), \"\/ranks\/Pink.txt\")\n                              , header = TRUE\n                              , stringsAsFactors = FALSE\n                            )\n\ndf_rankings_rihanna &lt;- read.delim(paste0(getwd(), \"\/ranks\/Rihanna.txt\")\n                               , header = TRUE\n                               , stringsAsFactors = FALSE\n                              )\n\ndf_rankings_taylorswift &lt;- read.delim(paste0(getwd(), \"\/ranks\/Taylor-Swift.txt\")\n                                    , header = TRUE\n                                    , stringsAsFactors = FALSE\n                                    )\n\ndf_rankings_u2 &lt;- read.delim(paste0(getwd(), \"\/ranks\/U2.txt\")\n                            , header = TRUE\n                            , stringsAsFactors = FALSE\n                            )\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Step 1.03<\/strong> Function to Replace White Space<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The function will replace the line feeds, tabs or any white space in the peek_rank column. <\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# update the data frames\n# ----------------------------------------------------------------------------\nreplace_empty &lt;- function(textcontent){\n# remove line feeds, tabs, and white space\n  if(\"factor\" %in% class(textcontent)){\n    textcontent &lt;- as.character(textcontent)\n  }\n  replacement_list &lt;- list(\"\\n\" = \" \", \"\\t\" = \"\t\")\n  textcontent &lt;- ifelse(textcontent==\"\", \"#1 on\" , textcontent)\n  textcontent &lt;- gsubfn(\".\" , replacement_list,textcontent)\n  \n  return(textcontent)\n}<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1.04 Replace the Data Frame<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For each artist, take the data frame will have four columns.<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li><strong>artist<\/strong>: is the name of the artist<\/li><li><strong>song_title:<\/strong> name of the song<\/li><li><strong>peek_rank<\/strong>: the highest position the song reached on the Billboard Hot 100 rankings<\/li><li><strong>peek_date<\/strong>: the date the song reached its highest rank on the Billboard Hot 100 rankings<\/li><\/ol>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># -- Drake\ndf_rankings_drake &lt;- df_rankings_drake %&gt;%\n                      transmute(artist = \"Drake\"\n                                ,song_title = song_title\n                                ,peek_rank = replace_empty(peek_rank)\n                                ,peek_date = mdy(peek_date)\n                                )\n\n# -- one direction\ndf_rankings_onedirection &lt;- df_rankings_onedirection %&gt;%\n                            transmute(artist = \"OneDirection\"\n                                      ,song_title = song_title\n                                      ,peek_rank = replace_empty(peek_rank)\n                                      ,peek_date = mdy(peek_date)\n                                      )\n\n# -- Pink\ndf_rankings_pink &lt;- df_rankings_pink %&gt;%\n                    transmute(artist = \"Pink\"\n                              ,song_title = song_title\n                              ,peek_rank = replace_empty(peek_rank)\n                              ,peek_date = mdy(peek_date)\n                    )\n\n# -- Rihanna\ndf_rankings_rihanna &lt;- df_rankings_rihanna %&gt;%\n                      transmute(artist = \"Rihanna\"\n                                ,song_title = song_title\n                                ,peek_rank = replace_empty(peek_rank)\n                                ,peek_date = mdy(peek_date)\n                      )\n\n# -- Taylor Swift\ndf_rankings_taylorswift &lt;- df_rankings_taylorswift %&gt;%\n                            transmute(artist = \"TaylorSwift\"\n                                      ,song_title = song_title\n                                      ,peek_rank = replace_empty(peek_rank)\n                                      ,peek_date = mdy(peek_date)\n                            )\n\n\n# -- U2\ndf_rankings_u2 &lt;- df_rankings_u2 %&gt;%\n                  transmute(artist = \"U2\"\n                            ,song_title = song_title\n                            ,peek_rank = replace_empty(peek_rank)\n                            ,peek_date = mdy(peek_date)\n                  )\n\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"match_song_ranks\"><strong>Step 2 \u2013 Match the Song Ranks<\/strong><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that the rankings files have been loaded and stored into data frames, the next step is to join the ranking files with the lyric files.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2.01 Load the necessary packages<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Load the necessary packages magrittr, dplyr, and readr.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# take the ranking files and merge with the song lists\n# ----------------------------------------------------------------------------\nlibrary(magrittr ,quietly = TRUE, warn.conflicts = FALSE)\nlibrary(dplyr ,quietly = TRUE, warn.conflicts = FALSE)\nlibrary(readr ,quietly = TRUE, warn.conflicts = FALSE)<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.02 Load the Lyrics into Data Frames<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Load each of the lyric .csv files that I created from the previous step into data frames.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># load the songs lists\ndf_songs_drake &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/Drake_lyrics.csv\")\n                                , header = TRUE\n                                , stringsAsFactors = FALSE\n)\n\ndf_songs_onedirection &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/One-Direction_lyrics.csv\")\n                                       , header = TRUE\n                                       , stringsAsFactors = FALSE\n)\n\ndf_songs_pink &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/pink_lyrics.csv\")\n                               , header = TRUE\n                               , stringsAsFactors = FALSE\n)\n\ndf_songs_rihanna &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/Rihanna_lyrics.csv\")\n                                  , header = TRUE\n                                  , stringsAsFactors = FALSE\n)\n\ndf_songs_taylorswift &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/Taylor-Swift_lyrics.csv\")\n                                      , header = TRUE\n                                      , stringsAsFactors = FALSE\n)\n\ndf_songs_u2 &lt;- read.csv(paste0(getwd(), \"\/lyrics\/album_song\/U2_lyrics.csv\")\n                             , header = TRUE\n                             , stringsAsFactors = FALSE\n)<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.03 Update the Data Frames Dropping the song_url Column<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">I will convert the data frame into a tibble, selecting all columns except the song_url column<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# update the data frames\n# ----------------------------------------------------------------------------\ndf_songs_drake        &lt;- as_tibble(df_songs_drake        %&gt;% select(-c(song_url)))\ndf_songs_onedirection &lt;- as_tibble(df_songs_onedirection %&gt;% select(-c(song_url)))\ndf_songs_pink         &lt;- as_tibble(df_songs_pink         %&gt;% select(-c(song_url)))\ndf_songs_rihanna      &lt;- as_tibble(df_songs_rihanna      %&gt;% select(-c(song_url)))\ndf_songs_taylorswift  &lt;- as_tibble(df_songs_taylorswift  %&gt;% select(-c(song_url)))\ndf_songs_u2           &lt;- as_tibble(df_songs_u2           %&gt;% select(-c(song_url)))\n\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.04 Merge Data Frames<\/h4>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# merge the data frames\n# ----------------------------------------------------------------------------\ndf_songs_drake        &lt;- df_songs_drake %&gt;% left_join(df_rankings_drake , by = \"song_title\")\ndf_songs_onedirection &lt;- df_songs_onedirection %&gt;% left_join(df_rankings_onedirection, by = \"song_title\")\ndf_songs_pink         &lt;- df_songs_pink %&gt;% left_join(df_rankings_pink , by = \"song_title\")\ndf_songs_rihanna      &lt;- df_songs_rihanna %&gt;% left_join(df_rankings_rihanna , by = \"song_title\")\ndf_songs_taylorswift  &lt;- df_songs_taylorswift %&gt;% left_join(df_rankings_taylorswift , by = \"song_title\")\ndf_songs_u2           &lt;- df_songs_u2 %&gt;% left_join(df_rankings_u2 , by = \"song_title\")\n\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.05 Drop Unnecessary Data Frames<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Since I no longer need the ranking data frames I will drop them from the global environment.<\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# drop the ranking data frames\n# ----------------------------------------------------------------------------\nrm(list=ls(pattern = \"df_rank\"))\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.06 Fix the Artist Column<\/h4>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# populate the missing values\n# ----------------------------------------------------------------------------\ndf_songs_drake        &lt;- df_songs_drake %&gt;% mutate(artist = \"Drake\")\ndf_songs_onedirection &lt;- df_songs_onedirection %&gt;% mutate(artist = \"One-Direction\")\ndf_songs_pink         &lt;- df_songs_pink %&gt;% mutate(artist = \"Pink\")\ndf_songs_rihanna      &lt;- df_songs_rihanna %&gt;% mutate(artist = \"Rihanna\")\ndf_songs_taylorswift  &lt;- df_songs_taylorswift %&gt;% mutate(artist = \"Taylor-Swift\")\ndf_songs_u2           &lt;- df_songs_u2 %&gt;% mutate(artist = \"U2\")\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.07 Merge the Data Frames<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Since all of the columns in all of the data frames are same I can use the <\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# merge the data frames\n# ----------------------------------------------------------------------------\ndf_songs &lt;- bind_rows(df_songs_drake \n                  ,df_songs_onedirection\n                  ,df_songs_pink\n                  ,df_songs_rihanna\n                  ,df_songs_taylorswift\n                  ,df_songs_u2)\n\ndf_backup_songs &lt;- df_songs\n\nrm(list=ls(pattern = \"df_songs_\"))<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.08 Clean Up and Load Lyrics into Data Frame<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Need to clean up the peek_rank column in the data frame. need to remove the hash symbol (#), and phrase &#8221; on&#8221;.  Updating the column values will allow the column to be converted to an integer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next I need to clean up some of the specific song titles. In the next step while creating the models, it won&#8217;t like ellipses (&#8220;&#8230;&#8221;) or double quotes for labeling in the model. The song title isn&#8217;t part of the model, just used as part of the unique identifier. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next I created a custom function to get the lyrics from the flat files that I created in the previous step. I then insert the lyrics in to the data frame for each song. <\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# convert peek_rank to an integer\n# ----------------------------------------------------------------------------\ndf_songs &lt;- df_songs %&gt;% mutate(peek_rank = stringr::str_replace(peek_rank,\"#\",\"\"))\ndf_songs &lt;- df_songs %&gt;% mutate(peek_rank = stringr::str_replace(peek_rank,\" on\",\"\"))\ndf_songs &lt;- df_songs %&gt;% mutate(peek_rank = as.integer(peek_rank))\n\n# ----------------------------------------------------------------------------\n# clean up an invalid song value\n# ----------------------------------------------------------------------------\ndf_songs &lt;- df_songs %&gt;% mutate(song_title = if_else(song_title==\"...Ready For It?\"\n                                          , \"Ready For It?\" \n                                          , song_title))\ndf_songs &lt;- df_songs %&gt;% mutate(song_title = if_else(song_title=='The Crystal Ballroom (12\" Mix)'\n                                                     , \"The Crystal Ballroom (12 Mix)\" \n                                                     , song_title))\n\n# ----------------------------------------------------------------------------\n# get the lyric text from the files\n# ----------------------------------------------------------------------------\nget_lyric_text &lt;- function(base_dir, song_name){\n  lyric_text = read_file(paste0(getwd()\n                                , \"\/lyrics\/\" ,base_dir ,\"_Lyrics\/\" \n                                , song_name \n                                ,\".txt\"))\n  return(lyric_text)\n}\n# vectorize the function\nget_lyric_text_v &lt;- Vectorize(get_lyric_text)\n\n# load the lyrics into the dataframe\ndf_songs_lyrics &lt;- df_songs %&gt;% mutate(\n                    lyrics = get_lyric_text_v(artist, song_title)\n                    )\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.08 Add Feature Columns<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Add four additional columns to the data frame<\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>album_decade: The decade the album was released <\/li><li>charted: did the song appear on Billboard&#8217;s Hot 100 charts<\/li><li>NumberOne: was the song have a peek ranking of number one on the Billboard Hot 100 chart<\/li><li>chart_group: was the peek ranking of the song in the top 10, or top 100 on the Billboard Hot 100 chart<\/li><\/ol>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# add additional columns to the data\n# album_decade: decade album was released\n# charted: did the album chart\n# numberone: was it a number one song\n# chart_group: was it a top ten, 11-100, or not-charted\n# ----------------------------------------------------------------------------\ndf_songs_lyrics &lt;- df_songs_lyrics %&gt;% mutate(album_decade = as.integer(substr(album_year,1,3)) * 10)\ndf_songs_lyrics &lt;- df_songs_lyrics %&gt;% mutate(charted = ifelse(is.na(peek_rank), \"Not Charted\" , \"Charted\"))\ndf_songs_lyrics &lt;- df_songs_lyrics %&gt;% mutate(NumberOne = ifelse(is.na(peek_rank), FALSE, ifelse(peek_rank == 1, TRUE , FALSE)))\ndf_songs_lyrics &lt;- df_songs_lyrics %&gt;% mutate(chart_group = ifelse(is.na(peek_rank), \"Not Charted\"\n                                                          , ifelse(peek_rank &lt;= 10, \"Top 10\" , \"Top 100\")))\n<\/pre><\/div>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2.09 Write the Results to a Tab Separated File<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Lastly I will save the updated results into a tab separated file to be used in the next step, Model Prediction. <\/p>\n\n\n\n<div class=\"wp-block-urvanov-syntax-highlighter-code-block\"><pre class=\"lang:r decode:true \"># ----------------------------------------------------------------------------\n# save the data frame for future use\n# ----------------------------------------------------------------------------\n\nwrite_tsv(df_songs_lyrics\n          ,file.path(paste0(getwd(), \"\/df_song_lyrics.txt\"))\n          , na = \"NA\"\n          , append = FALSE\n          #, col_names = !append\n          , quote_escape = \"double\"\n          )\n\n\n\n\n<\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The data created in the previous step needs a little bit of cleaning up before we can get into the model building. It is a common step that needs to be undertaken to ensure that the data can be loaded into models without any issues. Part 3 of 4 Steps for Preparing the Data Clean [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[58,4,5,59],"tags":[],"series":[],"class_list":["post-372","post","type-post","status-publish","format-standard","hentry","category-datascience","category-code","category-r","category-songlyrics"],"_links":{"self":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/372","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/comments?post=372"}],"version-history":[{"count":8,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/372\/revisions"}],"predecessor-version":[{"id":415,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/372\/revisions\/415"}],"wp:attachment":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/media?parent=372"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/categories?post=372"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/tags?post=372"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/series?post=372"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}