├── .gitignore ├── NAMESPACE ├── .Rbuildignore ├── README-unnamed-chunk-4-1.png ├── README-unnamed-chunk-5-1.png ├── inst └── extdata │ ├── the_tyger.txt │ ├── cant_get_you_out_of_my_head.txt │ ├── rumor_has_it.txt │ └── formation.txt ├── DESCRIPTION ├── README.md ├── README.Rmd ├── man └── songsim.Rd └── R └── songsim.R /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | songsim.Rproj -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(songsim) 4 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README\.Rmd$ 4 | ^README-.*\.png$ 5 | -------------------------------------------------------------------------------- /README-unnamed-chunk-4-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimchoni/songsim/HEAD/README-unnamed-chunk-4-1.png -------------------------------------------------------------------------------- /README-unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gsimchoni/songsim/HEAD/README-unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /inst/extdata/the_tyger.txt: -------------------------------------------------------------------------------- 1 | Tyger Tyger. burning bright, 2 | In the forests of the night; 3 | What immortal hand or eye. 4 | Could frame thy fearful symmetry? 5 | In what distant deeps or skies. 6 | Burnt the fire of thine eyes? 7 | On what wings dare he aspire? 8 | What the hand, dare sieze the fire? 9 | And what shoulder, & what art, 10 | Could twist the sinews of thy heart? 11 | And when thy heart began to beat. 12 | What dread hand? & what dread feet? 13 | What the hammer? what the chain, 14 | In what furnace was thy brain? 15 | What the anvil? what dread grasp. 16 | Dare its deadly terrors clasp! 17 | When the stars threw down their spears 18 | And water'd heaven with their tears: 19 | Did he smile his work to see? 20 | Did he who made the Lamb make thee? 21 | Tyger Tyger burning bright. 22 | In the forests of the night: 23 | What immortal hand or eye. 24 | Dare frame thy fearful symmetry? 25 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: songsim 2 | Title: Visualize a song lyrics with a similarity matrix, a method first suggested by Colin Morris 3 | Version: 0.0.0.9000 4 | Date: 2017-10-15 5 | Authors@R: c( 6 | person("Giora", "Simchoni", email = "gsimchoni@gmail.com", role = c("aut", "cre")), 7 | person("Colin", "Morris", , "colin.morris@gmail.com", "aut") 8 | ) 9 | Description: This package holds a single function to calculate and visualize a "songsim" similarity matrix 10 | where cell (i, j) is filled if word i in a song's lyrics is the same as word j. This method was first 11 | suggested by Colin Morris (see URLs) 12 | URL: https://colinmorris.github.io/blog/weird-pop-songs, https://colinmorris.github.io/SongSim/, http://giorasimchoni.com/2017/10/16/2017-10-16-repeat-yourself-the-songsim-package/ 13 | Depends: R (>= 3.4.1) 14 | License: GPL-3 15 | Encoding: UTF-8 16 | LazyData: true 17 | RoxygenNote: 6.0.1 18 | Imports: purrr, 19 | reshape2 20 | Suggests: heatmaply 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | This package holds a single function to calculate and visualize a "songsim" similarity matrix where cell (i, j) is filled if word i in a song's lyrics is the same as word j. This method was first suggested by [Colin Morris](https://colinmorris.github.io/) (see links below). 3 | 4 | Install: 5 | 6 | ``` r 7 | devtools::install_github("gsimchoni/songsim") 8 | ``` 9 | 10 | Load: 11 | 12 | ``` r 13 | library(songsim) 14 | ``` 15 | 16 | Visualize Beyonce's Formation: 17 | 18 | ``` r 19 | path <- system.file("extdata", "formation.txt", package = "songsim") 20 | songsim(path) 21 | ``` 22 | 23 | ![](README-unnamed-chunk-4-1.png) 24 | 25 | Use `colorfulMode`: 26 | 27 | ``` r 28 | songsim(path, colorfulMode = TRUE, mainTitle = "Formation - Beyonce") 29 | ``` 30 | 31 | ![](README-unnamed-chunk-5-1.png) 32 | 33 | Use `interactiveMode` if you have the `heatmaply` package installed: 34 | 35 | ``` r 36 | songsim(path, interactiveMode = TRUE, singleColor = "blue") 37 | ``` 38 | 39 | (See live version [here](http://giorasimchoni.com/2017/10/16/2017-10-16-repeat-yourself-the-songsim-package/)) 40 | 41 | More information and examples [here](http://giorasimchoni.com/2017/10/16/2017-10-16-repeat-yourself-the-songsim-package/). 42 | 43 | More information from Colin Morris: 44 | 45 | - A blog post describing interesting "songsims" [here](https://colinmorris.github.io/blog/weird-pop-songs) 46 | 47 | - An interactive React (JS) demo with more examples [here](https://colinmorris.github.io/SongSim/) 48 | -------------------------------------------------------------------------------- /inst/extdata/cant_get_you_out_of_my_head.txt: -------------------------------------------------------------------------------- 1 | La la la la la la la la 2 | La la la la la la la la 3 | La la la la la la la la 4 | La la la la la la la la 5 | I just can't get you out of my head 6 | Boy your loving is all I think about 7 | I just can't get you out of my head 8 | Boy it's more than I dare to think about 9 | La la la la la la la la 10 | La la la la la la la la 11 | I just can't get you out of my head 12 | Boy your loving is all I think about 13 | I just can't get you out of my head 14 | Boy it's more than I dare to think about 15 | Every night, every day 16 | Just to be there in your arms 17 | Won't you stay 18 | Won't you lay 19 | stay forever and ever and ever and ever 20 | La la la la la la la la 21 | La la la la la la la la 22 | La la la la la la la la 23 | La la la la la la la la 24 | I just can't get you out of my head 25 | Boy your loving is all I think about 26 | I just can't get you out of my head 27 | Boy it's more than I dare to think about 28 | There's a dark secret in me 29 | Don't leave me locked in your heart 30 | Set me free 31 | Feel the need in me 32 | Set me free 33 | Stay forever 34 | And ever and ever and ever 35 | La la la la la la la la 36 | La la la la la la la la 37 | La la la la la la la la 38 | La la la la la la la la 39 | I just can't get you out of my head 40 | La la la la la la la la 41 | La la la la la la la la 42 | I just can't get you out of my head 43 | La la la la la la la la 44 | La la la la la la la la 45 | I just can't get you out of my head 46 | La la la la la la la la 47 | La la la la la la la la 48 | I just can't get you out of my head 49 | La la la la la la la la 50 | La la la la la la la la 51 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: 3 | md_document: 4 | variant: markdown_github 5 | --- 6 | 7 | 8 | 9 | ```{r, echo = FALSE} 10 | knitr::opts_chunk$set( 11 | collapse = TRUE, 12 | comment = "#>", 13 | fig.path = "README-" 14 | ) 15 | ``` 16 | 17 | This package holds a single function to calculate and visualize a "songsim" similarity matrix where cell (i, j) is filled if word i in a song's lyrics is the same as word j. This method was first suggested by [Colin Morris](https://colinmorris.github.io/) (see links below). 18 | 19 | Install: 20 | ```{r, eval = FALSE} 21 | devtools::install_github("gsimchoni/songsim") 22 | ``` 23 | 24 | Load: 25 | ```{r} 26 | library(songsim) 27 | ``` 28 | 29 | Visualize Beyonce's Formation: 30 | ```{r} 31 | path <- system.file("extdata", "formation.txt", package = "songsim") 32 | songsim(path) 33 | ``` 34 | 35 | Use `colorfulMode`: 36 | ```{r} 37 | songsim(path, colorfulMode = TRUE, mainTitle = "Formation - Beyonce") 38 | ``` 39 | 40 | Use `interactiveMode` if you have the `heatmaply` package installed: 41 | ```{r, eval = FALSE} 42 | songsim(path, interactiveMode = TRUE, singleColor = "blue") 43 | ``` 44 | (See live version [here](http://giorasimchoni.com/2017/10/16/2017-10-16-repeat-yourself-the-songsim-package/)) 45 | 46 | More information and examples [here](http://giorasimchoni.com/2017/10/16/2017-10-16-repeat-yourself-the-songsim-package/). 47 | 48 | More information from Colin Morris: 49 | 50 | * A blog post describing interesting "songsims" [here](https://colinmorris.github.io/blog/weird-pop-songs) 51 | 52 | * An interactive React (JS) demo with more examples [here](https://colinmorris.github.io/SongSim/) 53 | -------------------------------------------------------------------------------- /inst/extdata/rumor_has_it.txt: -------------------------------------------------------------------------------- 1 | She, she ain't real 2 | She ain't gonna be able to love you like I will 3 | She is a stranger 4 | You and I have history 5 | Or don't you remember 6 | Sure, she's got it all 7 | But, baby, is that really what you want 8 | Bless your soul, you've got your head in the clouds 9 | You made a fool out of you 10 | And, boy, she's bringing you down 11 | She made your heart melt 12 | But you're cold to the core 13 | Now rumor has it she ain't got your love anymore 14 | Rumor has it, ooh 15 | Rumor has it, ooh 16 | Rumor has it, ooh 17 | Rumor has it, ooh 18 | Rumor has it, ooh 19 | Rumor has it, ooh 20 | Rumor has it, ooh 21 | Rumor has it, ooh 22 | She is half your age 23 | But I'm guessing that's the reason that you stayed 24 | I heard you've been missing me 25 | You've been telling people things that you shouldn't be 26 | Like when we creep out and she ain't around 27 | Haven't you heard the rumors 28 | Bless your soul, you've got your head in the clouds 29 | You made a fool out of me 30 | And, boy, you're bringing me down 31 | You made my heart melt, yet I'm cold to the core 32 | But rumor has it I'm the one you're leaving her for 33 | Rumor has it, ooh 34 | Rumor has it, ooh 35 | Rumor has it, ooh 36 | Rumor has it, ooh 37 | Rumor has it, ooh 38 | Rumor has it, ooh 39 | Rumor has it, ooh 40 | Rumor has it, ooh 41 | All of these words whispered in my ear 42 | Tell a story that I cannot bear to hear 43 | Just 'cause I said it, it don't mean that I meant it 44 | People say crazy things 45 | Just 'cause I said it, don't mean that I meant it 46 | Just 'cause you heard it 47 | Rumor has it, ooh, 48 | Rumor has it, ooh, 49 | Rumor has it, ooh, 50 | Rumor has it, ooh, 51 | Rumor has it, ooh, 52 | Rumor has it, ooh, 53 | Rumor has it, ooh, 54 | Rumor has it, ooh, 55 | Rumor has it, ooh, 56 | Rumor has it, ooh, 57 | Rumor has it, ooh, 58 | Rumor has it, ooh, 59 | Rumor has it, ooh, 60 | Rumor has it, ooh 61 | But rumor has it he's the one I'm leaving you for 62 | -------------------------------------------------------------------------------- /man/songsim.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/songsim.R 3 | \name{songsim} 4 | \alias{songsim} 5 | \title{Calculating and Visualizing a "Song Similarity" matrix} 6 | \usage{ 7 | songsim(path = NULL, colorfulMode = FALSE, singleColor = "black", 8 | interactiveMode = FALSE, mainTitle = "", plotOptions = NULL, 9 | heatmaplyOptions = NULL, plotMatrix = TRUE) 10 | } 11 | \arguments{ 12 | \item{path}{Path to a txt file holding the song's lyrics} 13 | 14 | \item{colorfulMode}{A boolean indicating whether to plot the matrix in color 15 | (see @details), defaults to FALSE} 16 | 17 | \item{singleColor}{What is the color to use for a full matrix cell (see @details)} 18 | 19 | \item{interactiveMode}{A boolean indicating whether to plot the matrix in 20 | interactive mode using the `heatmaply` package (see @details), defaults to FALSE} 21 | 22 | \item{mainTitle}{plot's main title, defaults to an empty string} 23 | 24 | \item{plotOptions}{Additional parameters for the base `plot` function 25 | (non-interactive mode)} 26 | 27 | \item{heatmaplyOptions}{Additional parameters for the `heatmaply` function 28 | (non-interactive mode)} 29 | 30 | \item{plotMatrix}{A boolean indicating whether to plot the matrix, defaults to TRUE} 31 | } 32 | \value{ 33 | a list containing: 34 | \item{songMat}{a song similarity square matrix of dimensions no. of words x 35 | no. of words, containing all 0 and 1} 36 | \item{repetitiveness}{an experimental measure of repetitiveness which is the 37 | mean of the upper triangular part of song matrix} 38 | } 39 | \description{ 40 | This function will calculate the "song similarity" of a given song's lyrics 41 | stored in a text file. A cell (i, j) is filled if word i in a song's lyrics 42 | is the same as word j. This method was first suggested by Colin Morris 43 | (see URLs) 44 | } 45 | \details{ 46 | A cell (i, j) in a songsim square matrix is filled if word i in a song's lyrics 47 | is the same as word j. This simple rule would create fascintaing visualizations 48 | of songs lyrics as shown in the links below. 49 | 50 | If \code{colorfulMode} is set to TRUE, each word which appears more than once will be 51 | colored with its own color (currently only available with \code{interactiveMode} set to FALSE). 52 | 53 | If \code{interactiveMode} is set to TRUE and the user has the \code{heatmaply} package 54 | installed - the songsim matrix will be plotted using an interactive heatmap. 55 | 56 | The \code{singleColor} corresponds to the color a full cell is colored with. 57 | If in \code{colorfulMode} it would be the color of words which appear only once. 58 | } 59 | \note{ 60 | This function was only tested on typical pop songs or poems, it was not tested 61 | on large pieces of texts 62 | } 63 | \examples{ 64 | path <- system.file("extdata", "formation.txt", package = "songsim") 65 | songsim(path) 66 | } 67 | \references{ 68 | A blog post describing the package with more examples: 69 | \url{http://giorasimchoni.com/2017/08/08/2017-08-08-lambada-the-mocap-package/} 70 | 71 | A blog post by Colin Morris describing interesting "songsims": 72 | \url{https://colinmorris.github.io/blog/weird-pop-songs} 73 | 74 | An interactive React (JS) demo by Colin Morris with more examples: 75 | \url{https://colinmorris.github.io/SongSim/} 76 | } 77 | -------------------------------------------------------------------------------- /inst/extdata/formation.txt: -------------------------------------------------------------------------------- 1 | What happened at the New Wil'ins? 2 | Bitch, I'm back by popular demand 3 | Y'all haters corny with that Illuminati mess 4 | Paparazzi, catch my fly, and my cocky fresh 5 | I'm so reckless when I rock my Givenchy dress (stylin') 6 | I'm so possessive so I rock his Roc necklaces 7 | My daddy Alabama, Momma Louisiana 8 | You mix that negro with that Creole make a Texas bama 9 | I like my baby heir with baby hair and afros 10 | I like my negro nose with Jackson Five nostrils 11 | Earned all this money but they never take the country out me 12 | I got a hot sauce in my bag, swag 13 | 14 | Oh yeah, baby, oh yeah I, ohhhhh, oh, yes, I like that 15 | I did not come to play with you hoes, haha 16 | I came to slay, bitch 17 | I like cornbreads and collard greens, bitch 18 | Oh, yes, you besta believe it 19 | 20 | Y'all haters corny with that lluminati mess 21 | Paparazzi, catch my fly, and my cocky fresh 22 | I'm so reckless when I rock my Givenchy dress (stylin') 23 | I'm so possessive so I rock his Roc necklaces 24 | My daddy Alabama, Momma Louisiana 25 | You mix that negro with that Creole make a Texas bama 26 | I like my baby heir with baby hair and afros 27 | I like my negro nose with Jackson Five nostrils 28 | Earned all this money but they never take the country out me 29 | I got a hot sauce in my bag, swag 30 | 31 | I see it, I want it, I stunt, yellow-bone it 32 | I dream it, I work hard, I grind 'til I own it 33 | I twirl on them haters, albino alligators 34 | El Camino with the seat low, sippin' Cuervo with no chaser 35 | Sometimes I go off (I go off), I go hard (I go hard) 36 | Get what's mine (take what's mine), I'm a star (I'm a star) 37 | Cause I slay (slay), I slay (hey), I slay (okay), I slay (okay) 38 | All day (okay), I slay (okay), I slay (okay), I slay (okay) 39 | We gon' slay (slay), gon' slay (okay), we slay (okay), I slay (okay) 40 | I slay (okay), okay (okay), I slay (okay), okay, okay, okay, okay 41 | Okay, okay, ladies, now let's get in formation, cause I slay 42 | Okay, ladies, now let's get in formation, cause I slay 43 | Prove to me you got some coordination, cause I slay 44 | Slay trick, or you get eliminated 45 | 46 | When he fuck me good I take his ass to Red Lobster, cause I slay 47 | When he fuck me good I take his ass to Red Lobster, cause I slay 48 | If he hit it right, I might take him on a flight on my chopper, cause I slay 49 | Drop him off at the mall, let him buy some J's, let him shop up, cause I slay 50 | I might get your song played on the radio station, cause I slay 51 | I might get your song played on the radio station, cause I slay 52 | You just might be a black Bill Gates in the making, cause I slay 53 | I just might be a black Bill Gates in the making 54 | 55 | I see it, I want it, I stunt, yellow-bone it 56 | I dream it, I work hard, I grind 'til I own it 57 | I twirl on them haters, albino alligators 58 | El Camino with the seat low, sippin' Cuervo with no chaser 59 | Sometimes I go off (I go off), I go hard (I go hard) 60 | Get what's mine (take what's mine), I'm a star (I'm a star) 61 | Cause I slay (slay), I slay (hey), I slay (okay), I slay (okay) 62 | All day (okay), I slay (okay), I slay (okay), I slay (okay) 63 | We gon' slay (slay), gon' slay (okay), we slay (okay), I slay (okay) 64 | I slay (okay), okay (okay), I slay (okay), okay, okay, okay, okay 65 | Okay, okay, ladies, now let's get in formation, cause I slay 66 | Okay, ladies, now let's get in formation, cause I slay 67 | Prove to me you got some coordination, cause I slay 68 | Slay trick, or you get eliminated 69 | 70 | Okay, ladies, now let's get in formation, I slay 71 | Okay, ladies, now let's get in formation 72 | You know you that bitch when you cause all this conversation 73 | Always stay gracious, best revenge is your paper 74 | 75 | Girl, I hear some thunder 76 | Golly, look at that water, boy, oh lord 77 | -------------------------------------------------------------------------------- /R/songsim.R: -------------------------------------------------------------------------------- 1 | #' Calculating and Visualizing a "Song Similarity" matrix 2 | #' 3 | #' This function will calculate the "song similarity" of a given song's lyrics 4 | #' stored in a text file. A cell (i, j) is filled if word i in a song's lyrics 5 | #' is the same as word j. This method was first suggested by Colin Morris 6 | #' (see URLs) 7 | #' 8 | #' @param path Path to a txt file holding the song's lyrics 9 | #' @param colorfulMode A boolean indicating whether to plot the matrix in color 10 | #' (see @details), defaults to FALSE 11 | #' @param singleColor What is the color to use for a full matrix cell (see @details) 12 | #' @param interactiveMode A boolean indicating whether to plot the matrix in 13 | #' interactive mode using the `heatmaply` package (see @details), defaults to FALSE 14 | #' @param mainTitle plot's main title, defaults to an empty string 15 | #' @param plotOptions Additional parameters for the base `plot` function 16 | #' (non-interactive mode) 17 | #' @param heatmaplyOptions Additional parameters for the `heatmaply` function 18 | #' (non-interactive mode) 19 | #' @param plotMatrix A boolean indicating whether to plot the matrix, defaults to TRUE 20 | #' 21 | #' @return a list containing: 22 | #' \item{songMat}{a song similarity square matrix of dimensions no. of words x 23 | #' no. of words, containing all 0 and 1} 24 | #' \item{repetitiveness}{an experimental measure of repetitiveness which is the 25 | #' mean of the upper triangular part of song matrix} 26 | #' 27 | #' @details 28 | #' A cell (i, j) in a songsim square matrix is filled if word i in a song's lyrics 29 | #' is the same as word j. This simple rule would create fascintaing visualizations 30 | #' of songs lyrics as shown in the links below. 31 | #' 32 | #' If \code{colorfulMode} is set to TRUE, each word which appears more than once will be 33 | #' colored with its own color (currently only available with \code{interactiveMode} set to FALSE). 34 | #' 35 | #' If \code{interactiveMode} is set to TRUE and the user has the \code{heatmaply} package 36 | #' installed - the songsim matrix will be plotted using an interactive heatmap. 37 | #' 38 | #' The \code{singleColor} corresponds to the color a full cell is colored with. 39 | #' If in \code{colorfulMode} it would be the color of words which appear only once. 40 | #' 41 | #' @note 42 | #' This function was only tested on typical pop songs or poems, it was not tested 43 | #' on large pieces of texts 44 | #' 45 | #' @references 46 | #' A blog post describing the package with more examples: 47 | #' \url{http://giorasimchoni.com/2017/08/08/2017-08-08-lambada-the-mocap-package/} 48 | #' 49 | #' A blog post by Colin Morris describing interesting "songsims": 50 | #' \url{https://colinmorris.github.io/blog/weird-pop-songs} 51 | #' 52 | #' An interactive React (JS) demo by Colin Morris with more examples: 53 | #' \url{https://colinmorris.github.io/SongSim/} 54 | #' 55 | #' @export 56 | #' @examples 57 | #' path <- system.file("extdata", "formation.txt", package = "songsim") 58 | #' songsim(path) 59 | 60 | songsim <- function(path = NULL, colorfulMode = FALSE, 61 | singleColor = "black", interactiveMode = FALSE, 62 | mainTitle = "", plotOptions = NULL, 63 | heatmaplyOptions = NULL, 64 | plotMatrix = TRUE) { 65 | songLyrics <- readLines(path) 66 | 67 | songWords <- strsplit(paste0(songLyrics, collapse = " "), " ")[[1]] 68 | 69 | songWords <- tolower(gsub("[[:punct:]]", "", songWords)) 70 | 71 | songMat <- diag(1, length(songWords), length(songWords)) 72 | 73 | grid <- as.data.frame(which(lower.tri(songMat, diag = FALSE), arr.ind = TRUE)) 74 | 75 | repeatingWord <- function(i, j) { 76 | songMat[i, j] <<- ifelse(songWords[i] == songWords[j], 1, 0) 77 | } 78 | 79 | purrr::walk2(grid$row, grid$col, repeatingWord) 80 | 81 | songMat[upper.tri(songMat)] <- t(songMat)[upper.tri(songMat)] 82 | 83 | rownames(songMat) <- colnames(songMat) <- songWords 84 | 85 | if (plotMatrix) { 86 | if (interactiveMode) { 87 | if (!requireNamespace("heatmaply", quietly = TRUE)) { 88 | warning("interactiveMode = TRUE only possible if you have the heatmaply 89 | package installed, setting interactiveMode to FALSE") 90 | interactiveMode <- FALSE 91 | } 92 | if (colorfulMode) { 93 | warning("colorfulMode = TRUE only allowed with interactiveMode = TRUE, 94 | setting colorfulMode to FALSE") 95 | colorfulMode <- FALSE 96 | } 97 | } 98 | 99 | if (!is.color(singleColor)) { 100 | warning("singleColor could not be interpreted as a color, setting it to black") 101 | singleColor <- "black" 102 | } 103 | 104 | 105 | 106 | if (interactiveMode) { 107 | hm <- do.call(heatmaply::heatmaply, c(list(x = songMat, dendrogram = FALSE, 108 | limits = c(0, 1), 109 | showticklabels = FALSE, 110 | colors = c("white", singleColor), 111 | hide_colorbar = TRUE, 112 | plot_method = "plotly", 113 | main = mainTitle), 114 | heatmaplyOptions)) 115 | print(hm) 116 | 117 | } else { 118 | songMatR <- t(apply(songMat, 2, rev)) 119 | 120 | dimnames(songMatR) <- NULL 121 | 122 | songMatRLong <- reshape2::melt(songMatR) 123 | 124 | songMatRLong$color <- ifelse(songMatRLong$value == 1, singleColor, NA) 125 | 126 | if (colorfulMode) { 127 | 128 | dupWords <- unique(songWords[duplicated(songWords)]) 129 | 130 | rbColors <- rainbow(length(dupWords)) 131 | 132 | getRBColor <- function(Var1, Var2, value, color) { 133 | if (value == 1 && songWords[Var1] %in% dupWords) { 134 | rbColors[which(dupWords == songWords[Var1])] 135 | } else { 136 | color 137 | } 138 | } 139 | 140 | songMatRLong$color <- purrr::pmap_chr(songMatRLong, getRBColor) 141 | } 142 | .pardefault <- par(no.readonly = T) 143 | par(pty = "s") 144 | do.call(plot, c(list(x = songMatRLong$Var1, y = songMatRLong$Var2, 145 | col = songMatRLong$color, 146 | pch = 15, cex = 0.2 * 400/length(songWords), 147 | xaxt = "n", yaxt = "n", 148 | main = mainTitle, xlab = "", 149 | ylab = ""), 150 | plotOptions)) 151 | par(.pardefault) 152 | } 153 | } 154 | 155 | invisible(list(songMat = songMat, 156 | repetitiveness = mean(songMat[upper.tri(songMat)]))) 157 | } 158 | 159 | is.color <- function(x) { 160 | tryCatch(is.matrix(col2rgb(x)), 161 | error = function(e) FALSE) 162 | } 163 | --------------------------------------------------------------------------------