polarity(text.var, grouping.var = NULL, polarity.frame = qdapDictionaries::key.pol, constrain = FALSE, negators = qdapDictionaries::negation.words, amplifiers = qdapDictionaries::amplification.words, deamplifiers = qdapDictionaries::deamplification.words, question.weight = 0, amplifier.weight = 0.8, n.before = 4, n.after = 2, rm.incomplete = FALSE, digits = 3, ...)
NULL
generates
one word list for all text. Also takes a single grouping variable or a list
of 1 or more grouping variables.TRUE
polarity values are constrained to
be between -1 and 1 using the following transformation:
((1 - (1/(1 + exp(polarity)))) * 2) - 1
TRUE
text rows ending with qdap's
incomplete sentence end mark (|
) will be removed from the analysis.strip
.Returns a list of: allA dataframe of scores per row with:
groupA dataframe with the average polarity score by grouping variable:
digitsinteger value od number of digits to display; mostly internal use
polarity
- Approximate the sentiment (polarity) of text by grouping
variable(s).
The equation used by the algorithm to assign value to polarity of
each sentence fist utilizes the sentiment dictionary (Hu and Liu, 2004) to
tag polarized words. A context cluster (x_i^T
) of words is
pulled from around this polarized word (default 4 words before and two words
after) to be considered as valence shifters. The words in this context
cluster are tagged as neutral (x_i^0
), negator
(x_i^N
), amplifier (x_i^a
), or de-amplifier
(x_i^d
). Neutral words hold no value
in the equation but do affect word count (n
). Each polarized word is
then weighted w
based on the weights from the polarity.frame
argument and then further weighted by the number and position of the valence
shifters directly surrounding the positive or negative word. The researcher
may provide a weight c
to be utilized with amplifiers/de-amplifiers
(default is .8; deamplifier weight is constrained to -1 lower bound). Last,
these context cluster (x_i^T
) are summed and divided by the
square root of the word count (\sqrtn
) yielding an unbounded
polarity score (C
). Note that context clusters containing a
comma before the polarized word will only consider words found after the
comma.
C=x_i^2/\sqrt(n)
Where:
x_i^T=\sum((1 + c * (x_i^A - x_i^D)) * w(-1)^(\sumx_i^N))
x_i^A=\sum(w_neg * x_i^a)
x_i^D = max(x_i^D', -1)
x_i^D'=\sum(- w_neg * x_i^a + x_i^d)
w_neg= (\sumx_i^N) mod 2
The polarity score is dependent upon the polarity dictionary used.
This function defaults to the word polarity dictionary used by Hu, M., &
Liu, B. (2004), however, this may not be appropriate for the context of
children in a classroom. The user may (is encouraged) to provide/augment the
dictionary (see the sentiment_frame
function). For instance the word
"sick" in a high school setting may mean that something is good, whereas
"sick" used by a typical adult indicates something is not right or negative
connotation (deixis).
Also note that polarity
assumes you've run
sentSplit
.
Hu, M., & Liu, B. (2004). Mining opinion features in customer reviews. National Conference on Artificial Intelligence.
http://www.slideshare.net/jeffreybreen/r-by-example-mining-twitter-for
http://hedonometer.org/papers.html Links to papers on hedonometrics
## <strong>Not run</strong>: # with(DATA, polarity(state, list(sex, adult))) # (poldat <- with(sentSplit(DATA, 4), polarity(state, person))) # counts(poldat) # scores(poldat) # plot(poldat) # # poldat2 <- with(mraja1spl, polarity(dialogue, # list(sex, fam.aff, died))) # colsplit2df(scores(poldat2)) # plot(poldat2) # plot(scores(poldat2)) # cumulative(poldat2) # # poldat3 <- with(rajSPLIT, polarity(dialogue, person)) # poldat3[["group"]][, "OL"] <- outlier_labeler(scores(poldat3)[, # "ave.polarity"]) # poldat3[["all"]][, "OL"] <- outlier_labeler(counts(poldat3)[, # "polarity"]) # htruncdf(scores(poldat3), 10) # htruncdf(counts(poldat3), 15, 8) # plot(poldat3) # plot(poldat3, nrow=4) # qheat(scores(poldat3)[, -7], high="red", order.b="ave.polarity") # # ## Create researcher defined sentiment.frame # POLKEY <- sentiment_frame(positive.words, negative.words) # POLKEY # c("abrasive", "abrupt", "happy") %hl% POLKEY # # ## ANIMATION # #=========== # (deb2 <- with(subset(pres_debates2012, time=="time 2"), # polarity(dialogue, person))) # # bg_black <- Animate(deb2, neutral="white", current.speaker.color="grey70") # print(bg_black, pause=.75) # # bgb <- vertex_apply(bg_black, label.color="grey80", size=20, color="grey40") # bgb <- edge_apply(bgb, label.color="yellow") # print(bgb, bg="black", pause=.75) # # ## Save it # library(animation) # library(igraph) # library(plotrix) # # loc <- folder(animation_polarity) # # ## Set up the plotting function # oopt <- animation::ani.options(interval = 0.1) # # FUN <- function() { # Title <- "Animated Polarity: 2012 Presidential Debate 2" # Legend <- c(-1.1, -1.25, -.2, -1.2) # Legend.cex <- 1 # lapply(seq_along(bgb), function(i) { # par(mar=c(2, 0, 1, 0), bg="black") # set.seed(10) # plot.igraph(bgb[[i]], edge.curved=TRUE) # mtext(Title, side=3, col="white") # color.legend(Legend[1], Legend[2], Legend[3], Legend[4], # c("Negative", "Neutral", "Positive"), attributes(bgb)[["legend"]], # cex = Legend.cex, col="white") # animation::ani.pause() # }) # } # # FUN() # # ## Detect OS # type <- if(.Platform$OS.type == "windows") shell else system # # saveHTML(FUN(), autoplay = FALSE, loop = TRUE, verbose = FALSE, # ani.height = 500, ani.width=500, # outdir = file.path(loc, "new"), single.opts = # "'controls': ['first', 'play', 'loop', 'speed'], 'delayMin': 0") # # ## Detect OS # type <- if(.Platform$OS.type == "windows") shell else system # # saveHTML(FUN(), autoplay = FALSE, loop = TRUE, verbose = FALSE, # ani.height = 1000, ani.width=650, # outdir = loc, single.opts = # "'controls': ['first', 'play', 'loop', 'speed'], 'delayMin': 0") # # #=====================# # ## Complex Animation ## # #=====================# # library(animation) # library(grid) # library(gridBase) # library(qdap) # library(reports) # library(igraph) # library(plotrix) # library(gridExtra) # # deb2dat <- subset(pres_debates2012, time=="time 2") # deb2dat[, "person"] <- factor(deb2dat[, "person"]) # (deb2 <- with(deb2dat, polarity(dialogue, person))) # # ## Set up the network version # bg_black <- Animate(deb2, neutral="white", current.speaker.color="grey70") # bgb <- vertex_apply(bg_black, label.color="grey80", size=30, label.size=22, # color="grey40") # bgb <- edge_apply(bgb, label.color="yellow") # # ## Set up the bar version # deb2_bar <- Animate(deb2, as.network=FALSE) # # ## Generate a folder # loc2 <- folder(animation_polarity2) # # ## Set up the plotting function # oopt <- animation::ani.options(interval = 0.1) # # # FUN2 <- function(follow=FALSE, theseq = seq_along(bgb)) { # # Title <- "Animated Polarity: 2012 Presidential Debate 2" # Legend <- c(.2, -1.075, 1.5, -1.005) # Legend.cex <- 1 # # lapply(theseq, function(i) { # if (follow) { # png(file=sprintf("%s/images/Rplot%s.png", loc2, i), # width=650, height=725) # } # ## Set up the layout # layout(matrix(c(rep(1, 9), rep(2, 4)), 13, 1, byrow = TRUE)) # # ## Plot 1 # par(mar=c(2, 0, 2, 0), bg="black") # #par(mar=c(2, 0, 2, 0)) # set.seed(20) # plot.igraph(bgb[[i]], edge.curved=TRUE) # mtext(Title, side=3, col="white") # color.legend(Legend[1], Legend[2], Legend[3], Legend[4], # c("Negative", "Neutral", "Positive"), attributes(bgb)[["legend"]], # cex = Legend.cex, col="white") # # ## Plot2 # plot.new() # vps <- baseViewports() # # uns <- unit(c(-1.3,.5,-.75,.25), "cm") # p <- deb2_bar[[i]] + # theme(plot.margin = uns, # text=element_text(color="white"), # plot.background = element_rect(fill = "black", # color="black")) # print(p,vp = vpStack(vps$figure,vps$plot)) # animation::ani.pause() # # if (follow) { # dev.off() # } # }) # # } # # FUN2() # # ## Detect OS # type <- if(.Platform$OS.type == "windows") shell else system # # saveHTML(FUN2(), autoplay = FALSE, loop = TRUE, verbose = FALSE, # ani.height = 1000, ani.width=650, # outdir = loc2, single.opts = # "'controls': ['first', 'play', 'loop', 'speed'], 'delayMin': 0") # # FUN2(TRUE) # # #=====================# # library(animation) # library(grid) # library(gridBase) # library(qdap) # library(reports) # library(igraph) # library(plotrix) # library(gplots) # # deb2dat <- subset(pres_debates2012, time=="time 2") # deb2dat[, "person"] <- factor(deb2dat[, "person"]) # (deb2 <- with(deb2dat, polarity(dialogue, person))) # # ## Set up the network version # bg_black <- Animate(deb2, neutral="white", current.speaker.color="grey70") # bgb <- vertex_apply(bg_black, label.color="grey80", size=30, label.size=22, # color="grey40") # bgb <- edge_apply(bgb, label.color="yellow") # # ## Set up the bar version # deb2_bar <- Animate(deb2, as.network=FALSE) # # ## Set up the line version # deb2_line <- plot(cumulative(deb2_bar)) # # ## Generate a folder # loc2b <- folder(animation_polarity2) # # ## Set up the plotting function # oopt <- animation::ani.options(interval = 0.1) # # # FUN2 <- function(follow=FALSE, theseq = seq_along(bgb)) { # # Title <- "Animated Polarity: 2012 Presidential Debate 2" # Legend <- c(.2, -1.075, 1.5, -1.005) # Legend.cex <- 1 # # lapply(theseq, function(i) { # if (follow) { # png(file=sprintf("%s/images/Rplot%s.png", loc2b, i), # width=650, height=725) # } # ## Set up the layout # layout(matrix(c(rep(1, 9), rep(2, 4)), 13, 1, byrow = TRUE)) # # ## Plot 1 # par(mar=c(2, 0, 2, 0), bg="black") # #par(mar=c(2, 0, 2, 0)) # set.seed(20) # plot.igraph(bgb[[i]], edge.curved=TRUE) # mtext(Title, side=3, col="white") # color.legend(Legend[1], Legend[2], Legend[3], Legend[4], # c("Negative", "Neutral", "Positive"), attributes(bgb)[["legend"]], # cex = Legend.cex, col="white") # # ## Plot2 # plot.new() # vps <- baseViewports() # # uns <- unit(c(-1.3,.5,-.75,.25), "cm") # p <- deb2_bar[[i]] + # theme(plot.margin = uns, # text=element_text(color="white"), # plot.background = element_rect(fill = "black", # color="black")) # print(p,vp = vpStack(vps$figure,vps$plot)) # animation::ani.pause() # # if (follow) { # dev.off() # } # }) # # } # # FUN2() # # ## Detect OS # type <- if(.Platform$OS.type == "windows") shell else system # # saveHTML(FUN2(), autoplay = FALSE, loop = TRUE, verbose = FALSE, # ani.height = 1000, ani.width=650, # outdir = loc2b, single.opts = # "'controls': ['first', 'play', 'loop', 'speed'], 'delayMin': 0") # # FUN2(TRUE) # # ## Increased complexity # ## -------------------- # # ## Helper function to cbind ggplots # cbinder <- function(x, y){ # # uns_x <- unit(c(-1.3,.15,-.75,.25), "cm") # uns_y <- unit(c(-1.3,.5,-.75,.15), "cm") # # x <- x + theme(plot.margin = uns_x, # text=element_text(color="white"), # plot.background = element_rect(fill = "black", # color="black") # ) # # y <- y + theme(plot.margin = uns_y, # text=element_text(color="white"), # plot.background = element_rect(fill = "black", # color="black") # ) # # plots <- list(x, y) # grobs <- list() # heights <- list() # # for (i in 1:length(plots)){ # grobs[[i]] <- ggplotGrob(plots[[i]]) # heights[[i]] <- grobs[[i]]$heights[2:5] # } # # maxheight <- do.call(grid::unit.pmax, heights) # # for (i in 1:length(grobs)){ # grobs[[i]]$heights[2:5] <- as.list(maxheight) # } # # do.call("arrangeGrob", c(grobs, ncol = 2)) # } # # deb2_combo <- Map(cbinder, deb2_bar, deb2_line) # # ## Generate a folder # loc3 <- folder(animation_polarity3) # # # FUN3 <- function(follow=FALSE, theseq = seq_along(bgb)) { # # Title <- "Animated Polarity: 2012 Presidential Debate 2" # Legend <- c(.2, -1.075, 1.5, -1.005) # Legend.cex <- 1 # # lapply(theseq, function(i) { # if (follow) { # png(file=sprintf("%s/images/Rplot%s.png", loc3, i), # width=650, height=725) # } # ## Set up the layout # layout(matrix(c(rep(1, 9), rep(2, 4)), 13, 1, byrow = TRUE)) # # ## Plot 1 # par(mar=c(2, 0, 2, 0), bg="black") # #par(mar=c(2, 0, 2, 0)) # set.seed(20) # plot.igraph(bgb[[i]], edge.curved=TRUE) # mtext(Title, side=3, col="white") # color.legend(Legend[1], Legend[2], Legend[3], Legend[4], # c("Negative", "Neutral", "Positive"), attributes(bgb)[["legend"]], # cex = Legend.cex, col="white") # # ## Plot2 # plot.new() # vps <- baseViewports() # p <- deb2_combo[[i]] # print(p,vp = vpStack(vps$figure,vps$plot)) # animation::ani.pause() # # if (follow) { # dev.off() # } # }) # } # # FUN3() # # type <- if(.Platform$OS.type == "windows") shell else system # # saveHTML(FUN3(), autoplay = FALSE, loop = TRUE, verbose = FALSE, # ani.height = 1000, ani.width=650, # outdir = loc3, single.opts = # "'controls': ['first', 'play', 'loop', 'speed'], 'delayMin': 0") # # FUN3(TRUE) # # ##-----------------------------## # ## Constraining between -1 & 1 ## # ##-----------------------------## # ## The old behavior of polarity constrained the output to be between -1 and 1 # ## this can be replicated via the `constrain = TRUE` argument: # # polarity("really hate anger") # polarity("really hate anger", constrain=TRUE) # # #==================# # ## Static Network ## # #==================# # (poldat <- with(sentSplit(DATA, 4), polarity(state, person))) # m <- Network(poldat) # m # print(m, bg="grey97", vertex.color="grey75") # # print(m, title="Polarity Discourse Map", title.color="white", bg="black", # legend.text.color="white", vertex.label.color = "grey70", # edge.label.color="yellow") # # ## or use themes: # dev.off() # m + qtheme() # m + theme_nightheat # dev.off() # m+ theme_nightheat(title="Polarity Discourse Map") # # #===============================# # ## CUMULATIVE POLARITY EXAMPLE ## # #===============================# # # Hedonometrics # # #===============================# # poldat4 <- with(rajSPLIT, polarity(dialogue, act, constrain = TRUE)) # # polcount <- na.omit(counts(poldat4)$polarity) # len <- length(polcount) # # cummean <- function(x){cumsum(x)/seq_along(x)} # # cumpolarity <- data.frame(cum_mean = cummean(polcount), Time=1:len) # # ## Calculate background rectangles # ends <- cumsum(rle(counts(poldat4)$act)$lengths) # starts <- c(1, head(ends + 1, -1)) # rects <- data.frame(xstart = starts, xend = ends + 1, # Act = c("I", "II", "III", "IV", "V")) # # library(ggplot2) # ggplot() + theme_bw() + # geom_rect(data = rects, aes(xmin = xstart, xmax = xend, # ymin = -Inf, ymax = Inf, fill = Act), alpha = 0.17) + # geom_smooth(data = cumpolarity, aes(y=cum_mean, x = Time)) + # geom_hline(y=mean(polcount), color="grey30", size=1, alpha=.3, linetype=2) + # annotate("text", x = mean(ends[1:2]), y = mean(polcount), color="grey30", # label = "Average Polarity", vjust = .3, size=3) + # geom_line(data = cumpolarity, aes(y=cum_mean, x = Time), size=1) + # ylab("Cumulative Average Polarity") + xlab("Duration") + # scale_x_continuous(expand = c(0,0)) + # geom_text(data=rects, aes(x=(xstart + xend)/2, y=-.04, # label=paste("Act", Act)), size=3) + # guides(fill=FALSE) + # scale_fill_brewer(palette="Set1") # ## <strong>End(Not run)</strong>