Introducció

L’extensió Thanks del programari Mediawiki, instal·lada a la Viquipèdia en català i als altres projectes de la Fundació Wikimedia, facilita eines per que els editors s’enviïn agraïments per edicions concretes, com a manera ràpida de donar feedback positius per edicions productives, De cada agraïment queda públicament registrat l’emissor, el receptor i la data i hora.

Baixar i analitzar les dades dels agraïments pot servir per oferir una mirada a l’estructura de la comunitat d’editors i a l’hora ser un exercici interessant sobre com obtenir dades del web fent servir funcions de base R. Per tal de no entrebancar la lectura als lectors interessats en el primer objectiu (els agraïments), l’explicació sobre el codi s’ha concentrat als comentaris dins dels blocs de codi.

Obtenció de dades

# Establim el nombre de pàgines que llegirem.
n <- 25

Cada pàgina del registre dóna dades de 500 agraïments. Llegim les darreres 25 pàgines per tenir dades dels darrers 12500 agraïments.

# llegim el codi html de la pàgina del registre
lseg <- "https://ca.wikipedia.org/w/index.php?title=Especial:Registre&offset=&limit=500&type=thanks&user=&page=&wpdate=&tagfilter=&wpfilters%5B0%5D=newusers"
linagr <- c()
for (i in 1:n) {
  pag <- readLines(lseg,
                   encoding = "UTF-8")
  # Guardem les línies que contenen els agraïments
  linagr <- c(linagr, pag[grepl("li data-mw-logid", pag)])
  # Busquem l'enllaç a la següent pàgina del registre
  seg <- pag[grepl("500 anteriors", pag)]
  lseg <- gsub('^.*<a href=\\"(/w/index.php\\?title=Especial:Registre&amp;offset=.*&amp;limit=500&amp;type=thanks&amp;user=&amp;page=&amp;wpdate=&amp;tagfilter=&amp;wpfilters%5B0%5D=newusers)\\" class=\\"mw-nextlink\\" title=\\"Especial:Registre\\" rel=\\"next\\">500 anteriors</a>.*$',"\\1",seg[1])
  lseg <- paste0("https://ca.wikipedia.org",lseg)
  lseg <- gsub("&amp;", "&", lseg)
}
# Extraiem l'emissor i el receptor de cada agraïment
trosagr <- strsplit(linagr,"ha agraït")
usagr <- lapply(trosagr, function(x) gsub('^.*\\"Usu..?ri.?:(.*?)\\".*$',"\\1", x))
actpas <- as.data.frame(t(do.call("cbind", usagr)))
names(actpas) <- c("emissor", "receptor")
# Per a fer reproduïble l'estudi, extraiem les dates inicial i final:
dates <- gsub("^.*>(..:.*?)<.*$","\\1", c(trosagr[1], trosagr[length(trosagr)]))
# Format data per operar
adata <- function(x) {
  d0 <- as.Date(x, 
                tryFormats = "%H:%M, %d %b %Y")
  d1 <- x[is.na(d0)]
  d1 <- gsub(" 202", ". 202", d1)
  d1 <- as.Date(d1, 
                tryFormats = "%H:%M, %d %b %Y")
  d0[is.na(d0)] <- d1
  return(d0)
}
dates1 <- adata(dates)
periode <- dates1[1]-dates1[2]
units(periode) <- "days"
dies <- as.numeric(periode)

Les dades recollides corresponen a 12500 agraïments, que són els registrats entre 21:03, 6 juny 2021 i 22:59, 17 juny 2022 (376 dies), amb una mitjana de 33.24 agraïments per dia.

Quants agraïments cadascú

Aquests 12500 agraïments han estat enviats per 498 editors diferents cap a 1015 editors diferents (en conjunt 1195 editors diferents). Noteu el nombre notablement més gran de receptors que d’emissors.

Veiem la distribució del nombre d’agraïments emesos i rebuts per cada editor.

summary(as.vector(table(actpas$emissor)))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    1.00    2.00   25.10    8.75 1236.00

De mitjana els editors que han fet agraïments n’han fet 25.1 cada un, però la meitat d’aquests editors no n’ha fet més de 2.

hist(table(actpas$emissor), breaks="scott", 
     main="Agraïments emesos", xlab="Emesos", ylab="Usuaris")

Tant el sumari com l’histograma ens mostren una distribució molt asimètrica a la dreta, amb la majoria d’usuaris emetent molt pocs agraïments i amb uns pocs editors emetent-ne moltíssims. Ampliant la part baixa de l’histograma veiem que hi ha un gran nombre d’usuaris que han emès un sol agraïment:

hist(table(actpas$emissor), breaks=seq(.5,3000,1), xlim=c(0,40), 
     main="Agraïments emesos (detall)", xlab="Emesos", ylab="Usuaris")

Fent el mateix anàlisi amb els agraïments rebuts la conclusió és molt semblant.

summary(as.vector(table(actpas$receptor)))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    1.00    1.00   12.32    3.00  934.00

De mitjana els editors que han rebut agraïments n’han rebut 12.32 cada un, però la meitat d’aquests editors no n’ha rebut més de 1.

hist(table(actpas$receptor), breaks="scott", 
     main="Agraïments rebuts", xlab="Rebuts", ylab="Usuaris")

hist(table(actpas$receptor), breaks=seq(.5,3000,1), xlim=c(0,40), 
     main="Agraïments rebuts (detall)", xlab="Rebuts", ylab="Usuaris")

De fet, el nombre d’usuaris que han rebut un sol agraïment (587) encara és més gran que el d’usuaris que han emès un sol agraïment (206).

Principals emissors i receptors

Busquem qui són els editors amb major nombre d’agraïments emesos i d’agraïments rebuts (al final del document hi ha una versió estesa d’aquestes taules amb més editors que no caben en aquesta secció).

# Agrïments emesos
head(sort(table(actpas$emissor), decreasing = TRUE),20)
## 
##            Paucabot        Leptictidium      TaronjaSatsuma       Xavier Dengra 
##                1236                1095                 505                 476 
##         Amadalvarez            Alzinous               Aniol      General Basset 
##                 463                 428                 395                 369 
##          Cataleirxs          Pere prlpz      Mercè Piqueras              Capsot 
##                 323                 320                 261                 255 
## Alvaro Vidal-Abarca            Docosong              Yuanga            KajenCAT 
##                 238                 204                 196                 193 
##            Davidpar           Barcelona               Bsckr           Castellbo 
##                 175                 161                 156                 155
barplot(head(sort(table(actpas$emissor), decreasing = TRUE),18), cex.names=.6, las=2, main="Agraïments emesos")

# Agrïments rebuts
head(sort(table(actpas$receptor), decreasing = TRUE),20)
## 
##       Paucabot   Leptictidium     Pere prlpz    Amadalvarez     Cataleirxs 
##            934            623            597            467            398 
##       Alzinous  Xavier Dengra       Amortres       Docosong          Medol 
##            360            273            263            249            222 
## Mercè Piqueras       Vriullop  Jordi escarre       KajenCAT       Pallares 
##            216            193            190            185            174 
##        Jmrebes     Llumeureka      Castellbo   CarlesMartin         Capsot 
##            158            158            138            133            132
barplot(head(sort(table(actpas$receptor), decreasing = TRUE),18), cex.names=.6, las=2, main="Agraïments rebuts")

Podem veure que una fracció important dels agraïments s’intercanvien entre els usuaris més actius:

# busquem els emissors i receptors més freqüents per no atapeir les gràfiques
frequents <- c(names(head(sort(table(actpas$emissor), decreasing = TRUE),10)), 
               names(head(sort(table(actpas$receptor), decreasing = TRUE),10)))
frequents <- unique(frequents)
# i agrupem els altres
actpas0 <- actpas
actpas0$emissor[! actpas0$emissor  %in% frequents] <- "Altres"
actpas0$receptor[! actpas0$receptor  %in% frequents] <- "Altres"
# Els representem:
cols <- c("white",rainbow(length(frequents)))
pie(sort(table(actpas0$emissor), decreasing = TRUE), col=cols, cex=.8, main="Agraïments emesos")

pie(sort(table(actpas0$receptor), decreasing = TRUE), col=cols, cex=.8, main="Agraïments rebuts")

# Normalment es considera que un gràfic de sectors és una mala alternativa davant d'un gràfic de barres
# però aquí hagués estat difícil representar el grup "Altres" al mateix gràfic de barres
# que els editors que volem individualitzar.

Havíem vist que el nombre d’emissors és més gran que el de receptors. Veiem també que les emissions d’agraïments estan concentrades en poques mans, força més concentrades que les recepcions d’agraïments.

Podem comparar les dues distribucions representant-ne la funció de distribució empírica:

plot.ecdf(table(actpas$emissor), col="blue")
plot.ecdf(table(actpas$receptor), col="red", add=TRUE)
legend("bottomright", lty=1, col=c("red", "blue"), legend=c("receptor", "emissor"))

# Si les distribucions fossin menys asimètriques un boxplot podria fer
# la mateixa funció que la ecdf.

Com s’intuïa als histogrames, la distribució del nombre d’agraïments rebuts encara és més asimètrica que la d’agraïments emesos, amb un nombre molt gran d’usuaris rebent un nombre petit agraïments.

Són els mateixos?

Veiem que els emissors més freqüents d’agraïments no són exactament els receptors més freqüents, i que com a mínim hi ha una part de receptors que no han emès cap agraïment (perquè hi ha més editors rebent agraïments que emetent-ne). En aquesta secció estem interessats en comparar l’activitat de cada editor com a emissor amb la seva activitat com a receptor.

Representem el nombre d’agraïments emesos i rebuts per cadascú.

# Ajuntem en un data.frame les taules d'emissors i receptors
nagr <- merge(data.frame(nom=names(table(actpas$emissor)), emesos=as.vector(table(actpas$emissor))),
              data.frame(nom=names(table(actpas$receptor)), rebuts=as.vector(table(actpas$receptor))),
              all=TRUE)
nagr$emesos[is.na(nagr$emesos)] <- 0
nagr$rebuts[is.na(nagr$rebuts)] <- 0
# diagrama de dispersió
plot(emesos~rebuts, data=nagr)
abline(lm(emesos~rebuts, data=nagr), col="red", lty=2)
abline(a=0, b=1, col="blue")
# etiquetem els més freqüents
frequents <- c(names(head(sort(table(actpas$emissor), decreasing = TRUE),10)), 
               names(head(sort(table(actpas$receptor), decreasing = TRUE),10)))
frequents <- unique(frequents)
nagrfreq <- nagr[nagr$nom %in% frequents,]
text(nagrfreq$rebuts, nagrfreq$emesos, labels=nagrfreq$nom, cex=.6, col="darkgrey")
# llegenda
legend("bottomright", col=c("blue","red"), lty=c(1,2), legend=c("x=y","regressió"))

La línia blava separa els editors que han emès més agraïments que els que han rebut (a sobre) dels que n’han rebut més que els que han emès (a sota). Els que estan per sobre de la línia blava han de ser editors que s’esforcen a dinamitzar la comunitat i donen feedback positiu a altres editors. Per altra banda, queda a criteri del lector decidir si els que quedem clarament per sota de la línia blava som grans contribuïdors justament reconeguts o senzillament som uns desagraïts, insociables i mal educats que no agraïm res.

Seguim mirant fins a quin punt emissors i receptors són els mateixos:

emissors <- unique(actpas$emissor)
receptors <- unique(actpas$receptor)
tots <- unique(c(emissors, receptors))
er <- c(sum(emissors %in% receptors), sum(!(emissors %in% receptors)), sum(!(receptors %in% emissors)))
names(er) <- c("Emissor i receptor", "Emissor no receptor", "Receptor no emissor" )
barplot(er, main="Nombre d'editors")

O sigui, hi ha un gran nombre d’editors que reben agraïments per les seves edicions però que no agraeixen les d’altres editors, però també un nombre sorprenentment gran d’editors que emeten algun agraïment però no en reben cap.

Caldria veure com són d’actius aquests grups.

eer <- c(sum(actpas$emissor %in% receptors), sum(!(actpas$emissor %in% receptors)))
names(eer) <- c("Emissor i receptor", "Emissor no receptor")
barplot(eer, main="Nombre total d'agraïments emesos")

rer <- c(sum(actpas$receptor %in% emissors), sum(!(actpas$receptor %in% emissors)))
names(rer) <- c("Emissor i receptor", "Receptor no emissor")
barplot(rer, main="Nombre total d'agraïments rebuts")

O sigui, veiem que la gran majoria d’agraïments els reben editors que també n’emeten i, encara més, gairebé tots els agraïments són emesos per editors que també en reben. Els editors que només reben o només emeten agraïments, tot i ser un grup força gran d’editors, reben i emeten una part molt petita dels agraïments.

Parells

Aquest estudi no estaria complert sense buscar els agraïments més freqüents:

parells <- with(actpas, paste(emissor, "agraeix", receptor))
tpar <- sort(table(parells), decreasing = TRUE)
head(as.data.frame(tpar), 36)
##                                     parells Freq
## 1                    Paucabot agraeix Medol   71
## 2           Leptictidium agraeix Pere prlpz   69
## 3                    Aniol agraeix Paucabot   68
## 4                 Alzinous agraeix Paucabot   67
## 5                  Paucabot agraeix Unapeça   52
## 6             Leptictidium agraeix Amortres   51
## 7          Xavier Dengra agraeix Pere prlpz   51
## 8           Leptictidium agraeix Cataleirxs   50
## 9            Amadalvarez agraeix Pere prlpz   49
## 10                Paucabot agraeix Alzinous   48
## 11                 Paucabot agraeix Jmrebes   46
## 12                Paucabot agraeix Vriullop   46
## 13                Docosong agraeix Paucabot   44
## 14        Mercè Piqueras agraeix Pere prlpz   43
## 15              Paucabot agraeix Pere prlpz   43
## 16             Leptictidium agraeix Laurita   42
## 17            Paucabot agraeix Isidre blanc   42
## 18            Leptictidium agraeix Pallares   39
## 19              Pere prlpz agraeix Paucabot   39
## 20              Leptictidium agraeix Vallue   38
## 21             Paucabot agraeix Amadalvarez   38
## 22           Pere prlpz agraeix Amadalvarez   37
## 23       Xavier Dengra agraeix Leptictidium   37
## 24             Leptictidium agraeix Flamenc   36
## 25                Paucabot agraeix Docosong   36
## 26 Alvaro Vidal-Abarca agraeix Leptictidium   35
## 27            Leptictidium agraeix Paucabot   35
## 28                 Leptictidium agraeix Pcm   35
## 29          General Basset agraeix Docosong   34
## 30            Leptictidium agraeix CarlesVA   34
## 31          Mercè Piqueras agraeix Paucabot   34
## 32        Mercè Piqueras agraeix Cataleirxs   32
## 33           Paucabot agraeix Jordi escarre   32
## 34           Xavier Dengra agraeix Paucabot   32
## 35                Capsot agraeix Llumeureka   31
## 36              Cataleirxs agraeix Pallares   31

És interessant que entre els parells més freqüents hi apareixen editors que no són entre els emissors ni receptors més freqüents. Probablement sigui un indici que un bon nombre d’agraïments s’originen en feines, converses o col·laboracions concretes.

Apèndix 1: taula detallada

Més amunt s’han representat els emissors i receptors més freqüents deixant-ne fora molts per motiu d’espai. Aquí es recull una versió estesa de la mateixa taula.

nagr$total <- nagr$emesos+nagr$rebuts
nagrnet <- nagr[nagr$total>10,]
nagrnet <- nagrnet[order(nagrnet$total, decreasing=TRUE),]
knitr::kable(nagrnet, row.names=FALSE)
nom emesos rebuts total
Paucabot 1236 934 2170
Leptictidium 1095 623 1718
Amadalvarez 463 467 930
Pere prlpz 320 597 917
Alzinous 428 360 788
Xavier Dengra 476 273 749
Cataleirxs 323 398 721
TaronjaSatsuma 505 128 633
Aniol 395 110 505
Mercè Piqueras 261 216 477
Docosong 204 249 453
General Basset 369 54 423
Amortres 133 263 396
Capsot 255 132 387
KajenCAT 193 185 378
Medol 150 222 372
Yuanga 196 108 304
Jmrebes 141 158 299
Alvaro Vidal-Abarca 238 55 293
Castellbo 155 138 293
Jordi escarre 90 190 280
Davidpar 175 94 269
CarlesMartin 118 133 251
Jove 133 115 248
Flamenc 132 104 236
Barcelona 161 71 232
Bsckr 156 56 212
Vriullop 16 193 209
Pallares 27 174 201
Beusson 83 110 193
Vallue 89 103 192
AlbertRA 79 111 190
Arnaugir 119 69 188
Llumeureka 30 158 188
FranSisPac 64 120 184
Kippelboy 127 55 182
Pau Colominas 103 77 180
Isidre blanc 81 80 161
F3RaN 97 61 158
Townie 100 57 157
Laurita 66 83 149
Robertgarrigos 66 74 140
Unapeça 9 131 140
Pau Nemo 64 69 133
Sorenike 50 78 128
Mcapdevila 72 50 122
Jordiventura96 50 70 120
Pcm 19 99 118
Loupeter 14 92 106
MALLUS 45 60 105
Vulcano 76 28 104
Kowalskyn 47 48 95
KRLS 25 70 95
Manlleus 39 56 95
CarlesVA 3 90 93
Kette~cawiki 46 47 93
Lohen11 32 56 88
Marcmiquel 70 18 88
Josep Estruch Traité 62 24 86
Anna maria batalla 70 15 85
Jordirooca 51 33 84
Sjoel 53 31 84
Magenri 32 49 81
Willy31igd 34 43 77
Jaumellecha 42 32 74
Jmarchn 28 44 72
Lluis tgn 27 44 71
Dragonfly137 32 37 69
Crespinell (encara no existeix) 47 17 64
Joutbis 13 51 64
ESM 60 3 63
Solde 29 33 62
Brunnaiz 27 33 60
Tomeu87 31 28 59
Judesba 38 18 56
Gerard Viader 35 20 55
Ivan Avz F 10 43 53
Walden69 4 49 53
Josu PV 13 39 52
Catgirl 19 30 49
Alexis900 5 43 48
Tiputini 20 28 48
Varondán 18 30 48
Joandrés 17 28 45
Pilardenou999 3 42 45
J bullanga 24 16 40
Joan Gené 8 32 40
Quetz72 25 15 40
Socialdilema 2 36 38
Enric 10 27 37
Quelcom 2 35 37
Hasley 1 35 36
Misterspritz 16 20 36
Symposiarch (encara no existeix) 36 0 36
Jordi G 23 12 35
ReginaManresa 4 30 34
Mbosch 9 24 33
Smalde 12 21 33
Ferinancat 13 19 32
Rocafera 3 29 32
Maria Fullana de València 12 19 31
Vador Faura (encara no existeix) 17 14 31
Ignasi 7 23 30
PaliGol 14 15 29
Paracel63 23 6 29
Carmallola 17 11 28
Culturaactiva 19 8 27
Desesser 5 22 27
Theklan 7 20 27
Mcsmp 10 16 26
Paputx 5 21 26
Pdg 10 15 25
Queso y aceitunas 17 7 24
Xamil 12 12 24
Bloguer 9 14 23
Bodinejador 13 10 23
Jordi Roqué 7 16 23
Kuranes 14 9 23
Bestiasonica 2 20 22
FogueraC 10 12 22
Markus2801 11 11 22
Pere Sallavinera 10 12 22
Toniher 5 17 22
Arnandis 2 19 21
Catalaalatac 16 4 20
Cpratsferre 9 11 20
QuimGil 4 16 20
Riumors21 (encara no existeix) 18 2 20
B25es 1 18 19
Caminort 4 15 19
Darth vader 92 10 9 19
Enrospv 10 9 19
Montesita 2 17 19
Setze16 15 4 19
Sguastevi 9 10 19
Jordiff 11 7 18
Quelet 0 18 18
Rei Momo 13 5 18
Xvazquez 1 17 18
Davdde 7 10 17
Marinna 11 6 17
Pacopac 8 9 17
Paddy Mc Aloon (encara no existeix) 2 15 17
SGrabarczuk (WMF) 1 16 17
Victorlopezmoya 17 0 17
1997z 1 15 16
19Tarrestnom65 4 12 16
Galactic Thrasher 11 5 16
Hiperterminal 10 6 16
Kxont 0 16 16
Adebalma8 (encara no existeix) 14 1 15
Aemda 12 3 15
Jey 10 5 15
STei (WMF) 3 12 15
Eduard Farre 6 8 14
Lks.poch 7 7 14
Or8a 7 7 14
Sanmame (encara no existeix) 0 14 14
Caro de Segeda 11 2 13
ICR CMC (encara no existeix) 0 13 13
Lluís RD (encara no existeix) 0 13 13
Olímpic 1 12 13
Pons 0 13 13
Pundit 3 10 13
Qgil-WMF 4 9 13
RafelJuan 2 11 13
Wakamai 0 13 13
Banyeres 2 10 12
Biblioaprenent 12 0 12
Castell 3 9 12
Edu Rne 4 8 12
Josepko 6 6 12
Marraco 4 8 12
Desluqlop (encara no existeix) 11 0 11
El Mono Español 6 5 11
Herodotptlomeu 3 8 11
Raspilla Demekin 8 3 11