fix final set of typos before publication
[opensym2017_postmortem.git] / opensym2017_postmortem.Rmd
1 ---
2 title: "OpenSym 2017 Program Postmortem"
3 output: html_document
4 ---
5
6 ```{r setup, include=FALSE}
7 knitr::opts_chunk$set(echo = TRUE)
8 ```
9
10 ```{r, echo=FALSE}
11 library(data.table)
12 library(ggplot2)
13 library(xtable)
14 library(knitr)
15
16 reviews <- read.csv("opensym-reviews-20180113.csv", stringsAsFactors = FALSE)
17 colnames(reviews) <- gsub('_', '.', colnames(reviews))
18 reviews$date <- as.Date(reviews$date)
19 reviews$subreviewer[reviews$subreviewer == ""] <- NA
20 reviews$reviewer[reviews$reviewer == ""] <- NA
21
22 submissions <- read.csv("opensym-submissions-20180113.csv", stringsAsFactors=FALSE)
23 colnames(submissions) <- gsub('_', '.', colnames(submissions))
24
25 authors <- read.csv("opensym-authors-20180113.csv", stringsAsFactors=FALSE)
26 colnames(authors) <- gsub('_', '.', colnames(authors))
27 ```
28
29 ```{r echo=FALSE}
30 crop.scores <- function (sub.id, before=FALSE) {
31   d <- reviews[reviews$sub.id == sub.id,]
32   cut.off <- d[d$label == "Author response", "date"]
33   
34   # reduce it to everything before if we're before
35   if (before) {
36     d <- d[d$date < cut.off,]
37   }
38   
39   d <- d[grep('^Review ', d$label),]
40   
41   # remove duplicates keeping the final score in the zone
42   d <- d[sort.list(d$date, decreasing=TRUE),]
43   d <- d[!duplicated(d$label),]
44   d <- d[sort.list(d$date),]
45
46   return(d)
47 }
48
49 scores.before <- do.call("rbind", lapply(unique(reviews$sub.id), crop.scores, before=TRUE))
50 scores.after <- do.call("rbind", lapply(unique(reviews$sub.id), crop.scores))
51
52 avg.score.df <- function (d) {
53   tbl <- tapply(d$score, d$sub.id, mean)
54   data.frame(sub.id=as.integer(names(tbl)),
55              avg.score=as.numeric(tbl))
56   
57 }
58
59 scores <- merge(avg.score.df(scores.before), avg.score.df(scores.after), by="sub.id", suffixes=c(".before", ".after"))
60 scores$delta <- scores$avg.score.before - scores$avg.score.after
61
62 grid.tmp <- melt(scores, id.vars=c("sub.id"))
63
64 # build table of changes
65 scores$change <- NA
66 scores$change[scores$delta == 0] <- "none"
67 scores$change[scores$delta > 0] <- "decrease"
68 scores$change[scores$delta < 0] <- "increase"
69   
70 # merge in data about submissions
71 scores <-  merge(scores, submissions[,c("sub.id", "type", "result")],
72                  by="sub.id")
73
74 scores$decision <- "Rejected"
75 scores$decision[scores$type == "full paper" & scores$result == "ACCEPT"] <- "Accepted"
76 scores$decision[scores$type == "poster" & scores$result == "ACCEPT"] <- "Poster"
77
78 scores$sub.id <- ordered(scores$sub.id, levels=scores$sub.id[sort.list(scores$avg.score.after)])
79 scores.after$sub.id <- ordered(scores.after$sub.id, levels=levels(scores$sub.id))
80 ```
81
82 The [International Symposium on Open Collaboration](http://www.opensym.org/) (*OpenSym*, formerly *WikiSym*) is the premier academic venue exclusively focused on scholarly research into open collaboration. OpenSym is an [ACM](http://www.acm.org/) conference which means that, like conferences in computer science, it's really more like a journal that gets published once a year than it is like most social science conferences. The "journal", in this case, is called the *Proceedings of the International Symposium on Open Collaboration* and it consists of final copies of papers which are typically also presented at the conferece. Like journal articles, papers that are published in the proceedings are not typically published elsewhere.
83
84 Along with [Claudia Müller-Birn](https://www.clmb.de/) from the [Freie Universtät Berlin](http://www.fu-berlin.de/), I served as the *Program Chair* for OpenSym 2017. For the social scientists reading this, the role of program chair is similar to being an editor for a journal. My job was not to organize keynotes or logistics at the conference—that is the job of the General Chair.  Indeed, in the end I didn't even attend the conference! Along with Claudia, my role as Program Chair was to recruit submissions, recruit reviewers, coordinate and manage the review process, make final decisions on papers, and ensure that everything makes it into the published proceedings in good shape.
85
86 In OpenSym 2017, we made several changes to the way the conference has been run:
87
88 * In previous years, OpenSym had tracks on topics like free/open source software, wikis, open innovation, open education, and so on. In 2017, **we used a single track model**.
89 * Because we eliminated tracks, we also eliminated track-level chairs. Instead, **we appointed Associate Chairs or ACs**.
90 * **We eliminated page limits and the distinction between full papers and notes**.
91 * **We allowed authors to write rebuttals before reviews were finalized.** Reviewers and ACs were allowed to modify their reviews and decisions based on rebuttals.
92 * To assist in assigning papers to ACs and reviewers, **we made extensive use of bidding**. This means we had to recruit the pool of reviewers before papers were submitted.
93
94 Although each of these things have been tried in other conferences, or even piloted within individual tracks in OpenSym, all were new to OpenSym in general.
95
96 # Overview
97
98 ```{r, echo=FALSE, results="asis"}
99 # two papers were originally submitted as posters
100 num.papers.accepted <- table(submissions$result == "ACCEPT" & submissions$type == "full paper")["TRUE"]
101
102 tbl.tmp <- as.data.frame(rbind(
103   list("Papers submitted",
104       nrow(submissions) -2),  # HARD CODED!!
105   list("Papers accepted",
106        num.papers.accepted),
107   list("Acceptance rate", 
108        paste(round(num.papers.accepted / (nrow(submissions) - 2)*100), "%", sep="")),
109   list("Posters submitted", 
110        2), # HARD CODED!!
111   list("Posters presented", 
112        table(submissions$result == "ACCEPT" & submissions$type == "poster")["TRUE"]),
113   list("Associate Chairs",
114        8),
115   list("PC Members",
116        length(na.omit(unique(c(reviews$reviewer, reviews$subreviewer))))),
117   list("Authors",
118        length(unique(authors$author))),
119   list("Author countries",
120        length(unique(authors$country)))
121   ))
122
123 colnames(tbl.tmp) <- c("Statistics", "")
124   
125 kable(tbl.tmp)
126 ```
127
128 The program was similar in size to the last 2-3 years in terms of the number of submissions. OpenSym is a small but mature and stable venue for research on open collaboration. This year was also similar, although slightly more competitive, in terms of the conference acceptance rate (`r round(num.papers.accepted / (nrow(submissions) - 2)*100)`%—it had been slightly above 50% in previous years).
129
130 As in recent years, there were more posters presented than submitted because the PC found that some rejected work, although not ready to be published in the proceedings, was promising and advanced enough to be presented as a poster at the conference. Authors of posters submitted 4-page extended abstracts for their projects which were published in a "*Companion to the Proceedings*."
131
132 # Topics
133
134 Over the years, OpenSym has established a clear set of niches. Although we eliminated tracks, we asked authors to choose from a set of categories when submitting their work. These categories are similar to the tracks at OpenSym 2016. Interestingly, a number of authors selected more than one category. This would have led to difficult decisions in the old track-based system.
135
136 ```{r topics, echo=FALSE}
137 submissions$topic <- sub(", esp. Wikis and Social Media", '', submissions$topic)
138 submissions$topic.nums <- sapply(strsplit(submissions$topic, ", "), length)
139
140 # create a list of topics
141 topics <- data.frame(topic=unlist(strsplit(submissions$topic, ", ")),
142                      sub.id=unlist(lapply(1:nrow(submissions), 
143                                           function (i) { rep(submissions$sub.id[i], submissions$topic.nums[i]) })))
144
145 # add decisions
146 topics <- merge(topics, scores[,c("sub.id", "decision")], by="sub.id")
147 topics$topic <- factor(topics$topic, levels=names(sort(table(topics$topic))))
148
149 ggplot(data=topics) + aes(x=topic, fill=decision) + 
150   geom_bar() + 
151   scale_y_continuous("Count") + 
152   scale_x_discrete("") +
153   coord_flip() +
154   scale_fill_discrete("Decision") +
155   theme_minimal() +
156   theme(legend.position="bottom", legend.direction = "horizontal")
157 ```
158
159 The figure above shows a breakdown of papers in terms of these categories as well as indicators of how many papers in each group were accepted. Research on FLOSS and Wikimedia/Wikipedia continue to make up a sizable chunk of OpenSym's submissions and publications. That said, these now make up a minority of total submissions. Although Wikipedia and Wikimedia research made up a smaller proportion of the submission pool, it was accepted at a higher rate. Also notable is the fact that 2017 saw an uptick in the number of papers on open innovation. I suspect this was due, at least in part, to work by the General Chair [Lorraine Morgan's](https://www.nuigalway.ie/our-research/people/lorrainemorgan/) involvement (she specializes in that area). Somewhat surprisingly to me, we had a number of submission about Bitcoin and blockchains. These are natural areas of growth for OpenSym but have never been a big part of work in our community in the past.
160
161 # Scores and Reviews
162
163 As in previous years, review was single blind in that reviewers' identities are hidden but authors identities are not. Each papers received between 3 and 4 reviews plus a metareview by the Associate Chair assigned to the paper. All papers received 3 reviews but ACs were encouraged to call in a 4th reviewer at any point in the process.  In addition to the text of the reviews, we used a -3 to +3 scoring system where papers that are seen as borderline will be scored as 0. Reviewers scored papers using full-point increments.
164
165 ```{r, echo=FALSE}
166 ## generate the score graphs
167 ggplot(data=scores) + aes(x=sub.id) + 
168   geom_hline(yintercept = 0, color="orange") +
169   geom_line(data=scores.after, aes(y=score), color="grey") + 
170   geom_point(aes(y=avg.score.after, color=decision)) + 
171   scale_x_discrete("", limits=levels(scores$sub.id), labels=c()) +
172   scale_y_continuous("Reviewer Score") +
173   scale_color_discrete("Final Decision") +
174   theme_minimal() +
175   theme(legend.position="bottom", legend.direction="horizontal")
176 ```
177
178
179 The figure above shows scores for each paper submitted. The vertical grey lines reflect the distribution of scores where the minimum and maximum scores for each paper are the ends of the lines. The colored dots show the arithmetic mean for each score (unweighted by reviewer confidence). Colors show whether the papers were accepted, rejected, or presented as a poster. It's important to keep in mind that two papers were *submitted* as posters.
180
181 Although Associate Chairs made the final decisions on a case-by-case basis, every paper that had an average score of less than 0 (the horizontal orange line) was rejected or presented as a poster and most (but not all) papers with positive average scores were accepted. Although a positive average score seemed to be a requirement for publication, negative individual scores weren't necessary showstoppers. We accepted `r table(unique(na.omit(scores.after$sub.id[scores.after$score < 0])) %in% submissions$sub.id[submissions$result == "ACCEPT" & submissions$type == "full paper"])["TRUE"]` papers with at least one negative score. We ultimately accepted `r num.papers.accepted` papers—`r round(num.papers.accepted / (nrow(submissions) - 2)*100)`% of those submitted.
182
183 # Rebuttals
184
185 This was the first time that OpenSym used a rebuttal or author response and we are thrilled with how it went. Although they were entirely optional, almost every team of authors used it! Authors of `r length(reviews[reviews$label == "Author response","sub.id"])` of our `r nrow(submissions)` submissions (`r round(length(reviews[reviews$label == "Author response","sub.id"]) / nrow(submissions)*100)`%!) submitted rebuttals.
186
187 ```{r, echo=FALSE}
188 # histogram of changes
189 # qplot(grid.tmp[grid.tmp$variable == "delta", "value"])
190
191 rebut.tbl <- table(scores[scores$sub.id %in% reviews[reviews$label == "Author response","sub.id"], "change"])
192
193 kable(data.frame("Lower"=rebut.tbl["decrease"],
194                  "Unchanged"=rebut.tbl["none"],
195                  "Higher"=rebut.tbl["increase"]),
196       row.names = FALSE)
197   
198 ```
199
200 The table above shows how average scores changed after authors submitted rebuttals. The table shows that rebuttals' effect was typically neutral or positive. Most average scores stayed the same but nearly two times as many increased as decreased in the post-rebuttal period. We hope that this made the process feel more fair for authors and I feel, having read them all, that it led to improvements in the quality of final papers.
201
202 # Page Lengths
203
204 In previous years, OpenSym followed most other venues in computer science by allowing submission of two kinds of papers: full papers which could be up to 10 pages long and short papers which could be up to 4. Following some other conferences, we eliminated page limits altogether. This is the text we used in [the OpenSym 2017 CFP](https://perma.cc/87QY-27FS):
205
206 > There is no minimum or maximum length for submitted papers. Rather, reviewers will be instructed to weigh the contribution of a paper relative to its length. Papers should report research thoroughly but succinctly: brevity is a virtue. A typical length of a “long research paper” is 10 pages (formerly the maximum length limit and the limit on OpenSym tracks), but may be shorter if the contribution can be described and supported in fewer pages— shorter, more focused papers (called “short research papers” previously) are encouraged and will be reviewed like any other paper. While we will review papers longer than 10 pages, the contribution must warrant the extra length. Reviewers will be instructed to reject papers whose length is incommensurate with the size of their contribution.
207
208 The following graph shows the distribution of page lengths across papers in our final program.
209
210 ```{r, echo=FALSE}
211 pdf.pages <- read.table("opensym2017-pdf_page_lengths.list")
212 colnames(pdf.pages) <- "pages"
213
214 ggplot(data=pdf.pages) + aes(x=pages) + geom_bar() + scale_x_continuous("Pages", breaks=seq(1, 14), labels=seq(1, 14)) + scale_y_continuous("Number of papers") + coord_flip() + theme_minimal()
215 ```
216
217 In the end `r table(pdf.pages$pages > 10)["TRUE"]` of `r num.papers.accepted` published papers (`r round(table(pdf.pages$pages > 10)["TRUE"] / num.papers.accepted * 100, 2)`%) were over 10 pages. More surprisingly, `r table(pdf.pages$pages < 10)["TRUE"]` of the accepted papers (`r round(table(pdf.pages$pages < 10)["TRUE"] / num.papers.accepted * 100, 2)`%) were below the old 10-page limit. Fears that some have expressed that page limits are the only thing keeping OpenSym authors from submitting enormous rambling manuscripts seems to be unwarranted—at least so far.
218
219 # Bidding
220
221 Although, I won't post any analysis or graphs, bidding worked well. With only two exceptions, every single assigned review was to someone who had bid "yes" or "maybe" for the paper in question and the vast majority went to people that had bid "yes." However, this comes with one major proviso: people that did not bid at all were marked as "maybe" for every single paper.
222
223 Given a reviewer pool whose diversity of expertise matches that in your pool of authors, bidding works fantastically. *But everybody needs to bid*. The only problems with reviewers we had were with people that had failed to bid. 
224 It might be reviewers who don't bid are less committed to the conference, more overextended, more likely to drop things in general, etc. It might also be that reviewers who fail to bid get poor matches which cause them to become less interested, willing, or able to do their reviews well and on time.
225
226 Having used bidding twice as chair or track-chair, my sense is that bidding is a fantastic thing to incorporate into any conference review process. The major limitations are that you need to build a PC before the conference (rather than finding the perfect reviewers for specific papers) and you have to find ways to incentivize or communicate the importance of getting your PC members to bid.
227
228 # Conclusions
229
230 The final results were [a fantastic collection of published papers](https://blog.communitydata.cc/opensym-2017-program/). Of course, it couldn't have been possible without the huge collection of [conference chairs, associate chairs, program committee members, external reviewers, and staff supporters](http://opensym.lero.ie/organisation/organization/).
231
232 Although we tried quite a lot of new things, my sense is that nothing we changed made things worse and many changes made things smoother or better. Although I'm not directly involved in organizing OpenSym 2018, I am on the OpenSym steering committee.  My sense is that most of the changes we made are going to be carried over this year.
233
234 Finally, it's also been announced that [OpenSym 2018 will be in Paris on August 22-24](http://www.opensym.org/os2018/). The call for papers should be out soon and **the OpenSym 2018 paper deadline has already been announced as March 15, 2018**. You should consider submitting! I hope to see you in Paris!
235
236 # This Analysis
237
238 OpenSym used the gratis version of [EasyChair](https://www.easychair.org/) to manage the conference which doesn't allow chairs to export data. As a result, data used in this this postmortem was scraped from EasyChair using two Python scripts. Numbers and graphs were created using a [knitr](https://yihui.name/knitr/) file that combines R visualization and analysis code with markdown to create the HTML directly from the datasets. I've made all the code I used to produce this analysis available in [this git repository](https://code.communitydata.cc/opensym2017_postmortem.git). I hope someone else finds it useful. Because the data contains sensitive information on the review process, I'm not publishing the data.
239

Community Data Science Collective || Want to submit a patch?