SHARE
TWEET

Smaller Metal Components

BenjaminLind Sep 21st, 2013 78 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. library(RCurl)
  2. library(compiler)
  3. library(igraph)
  4. library(tnet)
  5.  
  6. su<-function(x) #Sort the unique entries
  7.   return(sort(unique(x)))
  8. su<-cmpfun(su)
  9.  
  10. #Function to read a data table from online
  11. read.sstab<-function(theurl, ...){
  12.   #_theurl_ refers to the location of the data
  13.   #_..._ are parameters passed onto read.table
  14.   require(RCurl)
  15.   outtab<-getURL(theurl, ssl.verifypeer=FALSE)
  16.   outtab<-textConnection(outtab)
  17.   outtab<-read.table(outtab, sep="\t", ...)
  18.   return(outtab)
  19.   }
  20. read.sstab<-cmpfun(read.sstab)
  21.  
  22. #Download the most brutal data and name its parts
  23. metal.bands.df<-read.sstab("http://pastebin.com/raw.php?i=AA1SPz5K", header=TRUE, skip=4, as.is=TRUE, stringsAsFactors=FALSE, strip.white=TRUE, na.strings=c("NA", ""))
  24. colnames(metal.bands.df)[c(1,2)]<-c("group", "member")
  25. rm(read.sstab)
  26.  
  27. #Some members exit a band and later reunite, a band sometimes disassembles and later reforms
  28. #For our purposes here, we're going to ignore the time dimension
  29. #The missing data kind of sucks for it, too.
  30. #We also switch the columns as members form groups
  31. non.dupes<-which(duplicated(paste(metal.bands.df$group, metal.bands.df$member, sep="*"))==FALSE)
  32. metal.bands.df<-metal.bands.df[non.dupes,c("member", "group")]
  33. metal.bands.df$member<-gsub("&amp;", "&", metal.bands.df$member, fixed=TRUE)
  34. metal.bands.df$group<-gsub("&amp;", "&", metal.bands.df$group, fixed=TRUE)
  35.  
  36. #Retrieve the names for both members and groups.
  37. #Though a mighty package, tnet doesn't do labels, only integers.
  38. #_all.metal.names_ will be legend.
  39. all.metal.names<-unique(c(su(metal.bands.df$member), su(metal.bands.df$group)))
  40. metal.bands.df$member<-match(metal.bands.df$member, all.metal.names)
  41. metal.bands.df$group<-match(metal.bands.df$group, all.metal.names)
  42.  
  43. #Ignore the abyss that is metal's missing data
  44. miss.rows<-which((is.na(metal.bands.df$member) | is.na(metal.bands.df$group))==TRUE)
  45. metal.bands.df<-metal.bands.df[-miss.rows,]
  46. metal.bands.tn<-list(member.group=as.tnet(metal.bands.df, type="binary two-mode tnet"), group.member=as.tnet(metal.bands.df[,c("group", "member")], type="binary two-mode tnet"))
  47. rm(non.dupes, miss.rows)
  48.  
  49. #Spawn an igraph object
  50. metal.ig<-graph.data.frame(metal.bands.df[,c("member","group")], directed=FALSE)
  51. #"Alice Cooper" and other bands using only a member's full name are coded as bands, not musicians.
  52. #Some metal gods are just so epic they count as multiple people and one at the same time.
  53. V(metal.ig)$type<-V(metal.ig)$name%in%metal.bands.df$group
  54. V(metal.ig)$color<-rev(rainbow(2, s=.80, alpha=.80))[1+V(metal.ig)$type]
  55. V(metal.ig)$shape<-ifelse(V(metal.ig)$type, "square", "circle")
  56. V(metal.ig)$name<-all.metal.names[as.numeric(V(metal.ig)$name)]
  57.  
  58. metal.comps<-clusters(metal.ig)
  59. other.comps<-which(metal.comps$csize>=26)[-1]
  60. other.comps.csize<-metal.comps$csize[other.comps]
  61. names(other.comps.csize)<-other.comps
  62. other.comps.csize<-sort(other.comps.csize, decreasing=TRUE)
  63. #sum(other.comps.csize)/vcount(metal.ig) #About 4% of the actors in the network
  64. other.comps.bands<-sapply(names(other.comps.csize), function(x) return(sum(V(metal.ig)$type[which(metal.comps$membership==x)])))
  65. other.comps.musicians<-sapply(names(other.comps.csize), function(x) return(sum(!V(metal.ig)$type[which(metal.comps$membership==x)])))
  66. other.comps.bandnames<-sapply(names(other.comps.csize), function(x) return(paste(V(metal.ig)$name[which((metal.comps$membership==x)&(V(metal.ig)$type))], collapse="; ")))
  67. other.comps.csize<-data.frame(n=other.comps.csize, bands=other.comps.bands, musicians=other.comps.musicians, band.names=other.comps.bandnames)
  68. rm(other.comps.bands, other.comps.musicians, other.comps.bandnames)
  69.  
  70. cat("\n  Percent of Bands: ", round(100*sum(other.comps.csize$bands)/sum(V(metal.ig)$type)), "%\n", sep="")
  71. cat("\n  Percent of Musicians: ", round(100*sum(other.comps.csize$musicians)/sum(V(metal.ig)$type==FALSE)), "%\n", sep="")
  72.  
  73. print(other.comps.csize)
  74.  
  75. #Plot Dillinger Escape Plan and Tanner Wayne
  76. #These two should have ties to Mike Patton and Underoath, connecting them to the giant component
  77. miss.edges<-c(239, 760)
  78. miss.edges<-lapply(miss.edges, function(x){g<-induced.subgraph(metal.ig, which(metal.comps$membership==x)); g.lo<-layout.kamada.kawai(g, params=list(niter=5000, sigma=vcount(g)/16)); V(g)$x<-g.lo[,1]; V(g)$y<-g.lo[,2]; return(g)})
  79. png("Miss.edges.png", height=3, width=6, res=600, units="in", pointsize=8)
  80. par(mfrow=c(1,2))
  81. lapply(1:2, function(x) return(plot(miss.edges[[x]], vertex.size=10, vertex.label.cex=.45, vertex.label.color="black", vertex.label.family="sans", margin=.05)))
  82. dev.off()
  83.  
  84. plot(induced.subgraph(metal.ig, which(metal.comps$membership%in%c(239, 760))), vertex.size=3, vertex.label.cex=.4, vertex.label.family="sans")
  85.  
  86. #Plot the Japanese visual kei, OC metalcore, and Christian metal acts
  87. #Eighteen Visions should have a tie to Burn Halo through James Stephen Hart. Does not connect them to the giant component, though.
  88. #Whitecross has additional members, including at least one in King James.
  89.  
  90. niche.comps<-c(221, 172, 30)
  91. names(niche.comps)<-c("Japanese Visual\nKei Metal", "Orange County Straight\nEdge Metalcore", "Christian Metal")
  92. niche.comps<-lapply(niche.comps, function(x){g<-induced.subgraph(metal.ig, which(metal.comps$membership==x)); g.lo<-layout.kamada.kawai(g, params=list(niter=5000, sigma=vcount(g)/16)); V(g)$x<-g.lo[,1]; V(g)$y<-g.lo[,2]; return(g)})
  93. png("Niche.Comps.png", height=3, width=9, res=600, units="in", pointsize=8)
  94. par(mfrow=c(1,3))
  95. lapply(1:3, function(x) return(plot(niche.comps[[x]], vertex.size=5, vertex.label.cex=.75, vertex.label.color="black", vertex.label.family="sans", margin=.05, main=names(niche.comps)[[x]])))
  96. dev.off()
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top