El siguiente post nace de la necesidad de explicar un poco el procedimineto y las herramientas que usé para obtener los datos para los artículos donde analizo las letras de Folclore y Cuarteto:

Idea Principal

La idea principal surge de la curiosidad de entender o al menos chusmear a qué le cantaba el Folclore Argentino, luego gracias a una periodista interesada hice lo mismo pero para el Cuarteto Cordobés. Los análisis que se pueden realizar del conjunto de letras son muchos pero dado mi tiempo me bastaba con simplemente hacer un listado de las palabras más utilizadas.

Para responder esto necesitaba:

Voy a detallar a continuación el proceso para uno de los artículos y una de las páginas.

Herramientas

Obtención de Datos

Para obtener datos sobre letras de cuarteto, consulté varias páginas web. En este artículo me voy a enfocar en http://www.sonicomusica.com.

Lo que necesito hacer es:

Básicamente, un ciclo iterativo.

Extrayendo nombre y URL de los artistas

El elemento básico del que voy a partir es un data frame conteniendo nombre y URL de cada artista. Para ello:

baseUrl <- "http://www.sonicomusica.com"
paginaArtistas <- read_html(str_c(baseUrl, "/cuarteto/"))

nombreArtista <- paginaArtistas %>%
  html_nodes(".nameartist") %>%
  html_text()

urlArtista <- paginaArtistas  %>%
  html_nodes(".nameartist a") %>%
  html_attr("href")

dataArtistas <- data.frame(nombreArtista = nombreArtista,
                          urlArtista = str_c(baseUrl, urlArtista),
                          stringsAsFactors = FALSE)

Extracción de URL y Texto de Canciones

Ahora que tengo los datos de los Artistas, necesito empezar el ciclo de iteraciones para descargar URL de las canciones y posteriormente su letra. En vez de usar loops, quise utilizar el excelente paquete purrr. La lógica va a ser la siguiente:

  • Por cada elemento a extraer del HTML (link de cancion y letra) voy a definir una función.
  • Luego utilizaré dicha función, como argumento de la función map.
  • Encadenaré todas las acciones de lectura, extracción y limpieza en un pipeline de dplyr
getURLCanciones <- function(urlArtista){
  message(sprintf("Scrapeando URL canciones de: %s", urlArtista))
  read_html(urlArtista) %>%
    html_nodes(".listitems article a") %>%
    html_attr("href")
}

getLetraCancion <- function(urlCancion){
    message(sprintf(urlCancion))
    read_html(urlCancion, options = "RECOVER") %>%
    html_node("#lyricSong pre") %>%
    html_text()
}

Ahora anido todas las llamadas a estas funciones utilizando dplyr, tidyr y purr:

dataCanciones <- dataArtistas %>%
  mutate(urlCancion = urlArtista %>% map(getURLCanciones)) %>%
  unnest() %>%
  mutate(urlCancion = str_c(baseUrl, urlCancion),
         urlCancion = str_replace_all(urlCancion, " ", "%20")) %>%
  mutate(letraCancion = urlCancion %>% map(getLetraCancion))

Listo, con este código tenemos completa la lista de canciones y sus respectivas letras para comenzar con el análisis.

Limpieza de datos

Vamos a remover Letras no disponibles, finales de linea y palabras entre paréntesis.

dataCanciones <- dataCanciones %>%
    filter(letraCancion != "Letra no disponible") %>%
    mutate(letraCancion = gsub( " *\\(.*?\\) *", "", letraCancion),
         letraCancion = gsub( "\n", " ", letraCancion))

Análisis de Texto

Ahora resta contar las palabras más usadas en el texto. Debido a que el paquete no tiene stopwords en español, vamos a sacarlas de otro lado.

stopWords <- scan("http://www.webmining.cl/wp-content/uploads/2011/03/stopwords.es.txt", character())
customStopWords <- strsplit("vas pa vos bis has estribillo qe ie ii mmm mmmm eh oh na mee repite bom taka ye", " ")[[1]]
stopWords <- c(stopWords, customStopWords)

Ahora, con textos completos y limpios procedemos a sacar las métricas. Para ello recurriremos al paquete tidytext que con un simple metodo unnest_tokens pasa cualquier texto al formato tidy, utilizando como elemento básico la palabra.

topN <- 15
dataCanciones %>%
    select(nombreArtista, letraCancion) %>%
    unnest_tokens(palabra, letraCancion) %>%
    filter(!(palabra %in% stopWords)) %>%
    group_by(nombreArtista) %>%
    count(palabra) %>%
    arrange(nombreArtista, desc(n)) %>%
    slice(1:topN) %>%
    mutate(ranking = row_number()) %>%
    select(nombreArtista, palabra, ranking) %>%
    spread(nombreArtista, palabra)

Conclusión

El segundo interés que tenía es el de demostrar que con poco esfuerzo es posible generar datos de interés y contribuir con periodistas a generar notas. R, como herramienta de análisis, permite con poco esfuerzo acercar a Programadores y Periodistas; un acercamiento que es cada vez más necesario en la era digital y algo que promovemos fuertemente desde Open Data Córdoba.