# \#count JOSS reviewer by lang and their sectors

**URL:** https://discourse.julialang.org/t/count-joss-reviewer-by-lang-and-their-sectors/43614
**Category:** Community
**Created:** [July 24, 2020, 12:35pm UTC](https://discourse.julialang.org/t/count-joss-reviewer-by-lang-and-their-sectors/43614 "2020-07-24T12:35:11Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [July 24, 2020, 12:35pm UTC](https://discourse.julialang.org/t/count-joss-reviewer-by-lang-and-their-sectors/43614/1 "2020-07-24T12:35:11Z")

</div>

I was curious about which languages programmers-researchers in academic were using, so I went on the public list of reviewers of the Journal of Open Source Software (JOSS) available [here](https://docs.google.com/spreadsheets/d/1PAPRJ63yq9aPC1COLjaQp8mHmEq3rZUzwUYxTulyu78/edit#gid=856801822) and grab the data.

Here the result. Please note that although JOSS publish any open source software whenever the underlying language is open source or not, I highly suspect its activity is biased toward languages that are themselves open source.

```julia
*** The 20 most "best kwown" languages...
- python ( 68.74 %)
- r ( 27.52 %)
- c++ ( 18.85 %)
- c ( 13.91 %)
- matlab ( 8.3 %)
- java ( 7.26 %)
- fortran ( 5.76 %)
- javascript ( 4.79 %)
- julia ( 4.71 %)
- bash ( 3.07 %)
- go ( 2.02 %)
- perl ( 1.65 %)
- c# ( 1.57 %)
- rust ( 1.5 %)
- php ( 1.5 %)
- ruby ( 1.27 %)
- sql ( 1.12 %)
- scala ( 0.9 %)
- haskell ( 0.82 %)
- cuda ( 0.75 %)
*** The 20 most "known" languages...
- python ( 79.43 %)
- r ( 33.88 %)
- c++ ( 31.41 %)
- c ( 27.3 %)
- matlab ( 17.88 %)
- java ( 16.45 %)
- javascript ( 12.86 %)
- fortran ( 10.62 %)
- julia ( 8.45 %)
- bash ( 6.36 %)
- perl ( 4.49 %)
- php ( 3.89 %)
- c# ( 3.66 %)
- go ( 3.14 %)
- rust ( 2.99 %)
- ruby ( 2.84 %)
- sql ( 2.24 %)
- scala ( 2.09 %)
- html ( 1.72 %)
- haskell ( 1.5 %)
*** The 4 most common sectors for the 10 most "known" languages...
python : machine learning, bioinformatics, physics, statistics, 
r : bioinformatics, machine learning, statistics, genomics, 
c++ : machine learning, bioinformatics, physics, statistics, 
c : machine learning, bioinformatics, astrophysics, statistics, 
matlab : machine learning, image processing, statistics, physics, 
java : machine learning, bioinformatics, software engineering, data science, 
javascript : machine learning, bioinformatics, data science, statistics, 
fortran : physics, astrophysics, computational fluid dynamics, computational chemistry, 
julia : machine learning, statistics, physics, data science, 
bash : bioinformatics, genomics, machine learning, computational biology,

```

> **Source code**
>
> ```julia
> # Source: reviewer database of JOSS at https://docs.google.com/spreadsheets/d/1PAPRJ63yq9aPC1COLjaQp8mHmEq3rZUzwUYxTulyu78/edit#gid=856801822
> 
> using OdsIO
> 
> # Loading data..
> dataFile = "joss_reviewers_20200724.ods"
> db = ods_read(dataFile,range=((4,2),(1340,9)))
> 
> # removing email
> db = hcat(db[:,1:2],db[:,5:end])
> 
> # replacing "nothing"....
> # ..with empty string in the first three columns...
> for r in eachrow(db)
> for cidx in 1:3
> r[cidx] = isnothing(r[cidx]) ? "" : r[cidx]
> end
> end
> # ..and with zero in the number of reviews...
> for r in eachrow(db)
> for cidx in 4:6
> r[cidx] = isnothing(r[cidx]) ? 0 : r[cidx]
> end
> end
> 
> # Converting first 3 columns to string and last 4 to integers
> db = convert(Array{Union{String,Int64},2},db)
> 
> # Cleaning..
> for r in eachrow(db)
> for cidx in 1:3
> # ugly...
> r[cidx] = replace(replace(replace(replace(replace(r[cidx], '/'=>','), '('=>','), ')'=> ','), '\n'=> ',') , "and"=> ',') |> strip |> lowercase
> r[cidx] = replace(r[cidx],", " => ',') # to avoid empty data
> r[cidx] = replace(r[cidx]," ," => ',') # to avoid empty data
> r[cidx] = replace(r[cidx], r",$" => "") # remove ending comma
> 
> end
> end
> 
> # Establishing vocabolaries
> vocLangs = Set{String}()
> vocActivities = Set{String}()
> for (ridx,r) in enumerate(eachrow(db))
> ##if ridx > 20 break end
> for cidx in 1:2
> #=
> debug = strip.(split(r[cidx],','))
> for l in debug
> if l == ""
> println(l)
> println(ridx)
> println(cidx)
> end
> end
> =#
> if r[cidx] == "" continue end
> push!(vocLangs,strip.(split(r[cidx],','))...)
> end
> for cidx in 3:3
> if r[cidx] == "" continue end
> push!(vocActivities,strip.(split(r[cidx],','))...)
> end
> end
> vocLangs = collect(vocLangs)
> vocActivities = collect(vocActivities)
> langIdx = Dict{String,Int64}()
> [langIdx[l] = id for (id,l) in enumerate(vocLangs)]
> actIdx = Dict{String,Int64}()
> [actIdx[a] = id for (id,a) in enumerate(vocActivities)]
> 
> nLangs = length(vocLangs)
> nActs = length(vocActivities)
> nRecords = size(db,1)
> preferredLangCount = zeros(Int64,nLangs)
> competentLangCount = zeros(Int64,nLangs)
> actCountByLang = zeros(Int64,nLangs,nActs)
> 
> # Let's count!
> for r in eachrow(db)
> plangs = strip.(split(r[1],','))
> olangs = strip.(split(r[2],','))
> langs = union(Set(plangs),Set(olangs))
> acts = strip.(split(r[3],','))
> [preferredLangCount[langIdx[l]] += 1 for l in plangs if l != ""]
> [competentLangCount[langIdx[l]] += 1 for l in langs if l != ""]
> [actCountByLang[langIdx[l],actIdx[a]] += 1 for l in langs, a in acts if l != "" && a != ""]
> end
> 
> # Let's report:
> n = 20
> println("*** The $n most \"best kwown\" languages...")
> sortIdx = reverse(sortperm(preferredLangCount))[1:n]
> [println("- $(rpad(vocLangs[i],12))\t ( $(round(100*preferredLangCount[i]/nRecords,digits=2)) %)") for i in sortIdx]
> n = 20
> println("*** The $n most \"known\" languages...")
> sortIdx = reverse(sortperm(competentLangCount))[1:n]
> [println("- $(rpad(vocLangs[i],12))\t ( $(round(100*competentLangCount[i]/nRecords,digits=2)) %)") for i in sortIdx]
> 
> n = 10
> n2 = 4
> println("*** The $n2 most common sectors for the $n most \"known\" languages...")
> sortIdx = reverse(sortperm(competentLangCount))[1:n]
> for i in sortIdx
> lang = vocLangs[i]
> sortIdxActs = reverse(sortperm(actCountByLang[i,:]))[1:n2]
> print("$(rpad(lang,12)): \t")
> [print("$(vocActivities[j]), ") for j in sortIdxActs]
> print("\n")
> end
> 
> ```

---

<div class="post-metadata">

### Author: ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)
#### Post date: [July 24, 2020, 2:20pm UTC](https://discourse.julialang.org/t/count-joss-reviewer-by-lang-and-their-sectors/43614/2 "2020-07-24T14:20:39Z")

</div>

Interesting, thanks.

How does your code handle “ties” where people list more than one language or work area? Do you just count it as 1 “vote” for each? Not obvious from a quick read-through.

---

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [July 24, 2020, 4:32pm UTC](https://discourse.julialang.org/t/count-joss-reviewer-by-lang-and-their-sectors/43614/3 "2020-07-24T16:32:37Z")

</div>

For the first list I count the number of reviewer that have lang x as their primary choice (or x as one of their primary choices in very few cases).

For the second list I count the number of reviewers that have lang x in either the primary or the “other languages” they can review.

In both cases it doesn’t matter if they list 1 or 10 langs, if they have x I count them for x, and then I determine how many reviewers have lang x out of the total number of reviewers.

The percentages of the different langs don’t need to sum to 100.

Note that it remains just an approximation. For example there is one guy that said “all except Fortran”… and he will be counted for Fortran 😑

One can either manually clean the dB or use more advanced tools from natural language processing… this is just a quick and dirty script …
