Sustainability: ¿reflejo de la impa-ciencia?
Nota: El color de texto LigthBlue señala links
Sustainability es una de las principales revistas de la editorial de accesso abierto MDPI.
En 10 años pasó de ser una completa desconocida a ser hoy la cuarta revista por artículos publicados a nivel
mundial: 50 mil artículos y más de 130 mil citas.
Introducción
¿Ha llegado la cultura
de la impaciencia a la ciencia?
El rapid, fast manuscript handling ya es una política de marketing de algunas editoriales de revistas
científicas. Otras van directamente al grano haciendo mención al número de semanas que se tarda en publicar y a que
precio.
La ANECA, en su informe sobre editoriales
de acceso abierto, tuvo la intención de analizar la impaciencia mirando el tiempo que tarda un artículo en ser aceptado en la editorial MDPI pero no pudo
acceder a los datos. Según la ANECA los datos globales no están disponibles y los datos por artículo son
de
difícil acceso.
Está claro que el tiempo durante el cual un artículo está siendo evaluado -sea este mucho o poco- no garantiza
la
fiabilidad del resultado. Any scientific paper
can be wrong. No matter where it is published….
Sin embargo, en un contexto de recursos escasos: ¿es una asignación eficiente de recursos públicos el
que
un investigador pague el equivalente a 4 salarios IPREM para que su resultado se publique en el menor tiempo posible?
En este post resolvemos el problema de acceso a datos que tuvo la ANECA -adjuntamos el código más abajo-
y
mostramos que en menos de 40 días se acepta como válido el resultado científico de una investigación en
Sustainability.
España: el país que más invierte en Sustainability
España acumula cerca de 4.500
artículos publicados en Sustainability, siendo el país de europa
occidental con más publicaciones en esta revista.
En el gráfico se presenta el número de publicaciones en
Sustainability frente al número de investigadores
en universidades por país (datos de Eurostat). El área del círculo está correlacionada con el ratio de
publicaciones
a investigadores.
En el gráfico se observa que:
-
España supera a Italia en casi de 1.000 artículos pero con un número similar de PDIs.
-
Francia, con un 50% más de PDI que España, tiene 5 veces menos publicaciones en Sustainability.
-
Alemania, con el doble de PDIs, tiene la mitad de artículos que España.
En cuántos días se acepta un artículo en Sustainability
El informe de la ANECA sobre acceso abierto se propuso analizar los tiempos del proceso evaluación de una
publicación.
El problema que se encontró la ANECA con la editorial MDPI es que la información
sobre los tiempos de evaluación de una publicación era de díficil acceso por
lo
que no pudo disponer de datos para realizar el estudio. Citando al informe de la ANECA, “lamentablemente, no
existen datos globales para MDPI, si bien esta información sí aparece individualmente en cada uno de los
artículos que publica”.
En este post presentamos los resultados de extraer la información de la historia del proceso de evaluación
de
cada artículo utilizando un código de Python que se comparte más abajo. Aquí presentamos brevemente los
resultados del tiempo de publicación en la revista Sustainability de casi 14 mil artículos
publicados por investigadores de Alemania, España, Italia, Portugal y el Reino Unido.
La Tabla presenta la mediana, el primer y tercer cuartíl de los dias que tarda un artículo enviado a
Sustainability en el proceso hasta su publicación.
Sustainability: número de días en el
proceso de publicación
de un artículo
Proceso |
Recibido-Revisado |
Recibido-Aceptado |
Revisado-Aceptado |
Cuantiles |
25% |
50% |
75% |
25% |
50% |
75% |
25% |
50% |
75% |
|
|
|
|
|
|
|
|
|
|
2014 |
73.25 |
91.5 |
121.0 |
72.75 |
92.0 |
121.75 |
1.0 |
3.0 |
9.25 |
2016 |
44.00 |
64.0 |
86.0 |
52.00 |
72.0 |
91.00 |
2.0 |
6.0 |
11.00 |
2018 |
23.00 |
33.0 |
47.0 |
27.00 |
38.0 |
52.00 |
1.0 |
3.0 |
7.00 |
2020 |
21.00 |
29.0 |
41.0 |
24.00 |
33.0 |
46.00 |
1.0 |
3.0 |
6.00 |
2022 |
23.00 |
32.0 |
44.0 |
28.00 |
37.5 |
50.00 |
2.0 |
4.0 |
7.00 |
Si nos fijamos en la mediana, vemos que:
-
Un resultado de investigación es aceptado para su publicación en menos de 40 días.
-
En 1 mes un artículo es devuelto por los autores ya revisado.
-
La duración del proceso de evaluación ha disminuido significativamente entre 2014 y 2022.
-
Sólo pasan 4 días desde que la revista recibe la revisión y se acepta.
Notas:
-
Los datos hacen referencia a los artículos que han cerrado el ciclo de publicación. Nada se sabe de
aquellos artículos que han sido rechazados en el proceso de evaluación.
-
Sin embargo, la tasa de rechazo reportada por MDPI (el 57% de los artículos son rechazados)
no debería considerarse como una información fiable. Dado el plan de negocio de MDPI -con
más
de 400 revistas- podrían rechazarse artículos pero para ser reasignados a otra revista del grupo (i.e.,
contabilidad creativa). O sea, el dato de rechazos de MDPI es tan creible como de creible era el dato de listas de espera
en
la sanidad madrileña cuando reinaba Esperanza Aguirre.
¿Existen diferencias en el tiempo de evaluación según el tópico del artículo?
Dado que Sustainability publica una enorme variedad de temas podría resultar interesante analizar si
el
tiempo de evaluación está asociado a la “rareza” de un tópico.
Para intentar responder a esta pregunta hemos ordenado los tópicos de los más de 13.700 artículos publicados en
Sustainability por investigadores de Alemania, España, Italia, Portugal y Reino Unido utilizando la
información de abstracts y keywords.
A grandes rasgos, lo que hemos hecho es:
-
Hemos buscado similitudes en las más de las 70 mil keywords que definen los artículos con el objetivo
de
hacer una búsqueda guiada de temas, e.g., paraphrase mining.
-
Hemos analizado la clasificacion en tópicos utilizando diferentes metodologías, e.g. LDA, UMAP-HDBSCAN
o
directamente con BerTopic.
El gráfico presenta los tópicos utilizando Guided BerTopic donde las guías estaban basadas en las keywords más
usuales, con un minimum cluster size de 15 y obteniendo un coherence level de 0.51.
- Para analizar la asociación entre el tiempo de aceptación de un artículo y su pertenencia a la cola larga de
los tópicos se siguieron distintas vías.
- Por ejemplo: se definió un índice creciente en la probabilidad de ser un outlier no perteneciente a un
tópico a partir del outlier topic score de HDBSCAN y de la probabilidad de pertencencia a un tópico de
BerTopic; el tiempo de publicación se definió como el número de días entre que se recibe y es aceptado
dividido la media móvil centrada de cuatro dias alrededor de la fecha de publicación del artículo. A
partir de regresiones quantílicas en la cola larga de la distribución de tiempos no se observó ninguna
asociación significativa entre el tiempo que tarda en ser aceptado un artículo y su caractización como
“outlier”.
De estos análisis no hemos encontrado una asociación significativa entre la duración del proceso
de
aceptación de un artículo y su pertenencia a la cola larga.
Hasta aquí hemos llegado
El objetivo de este post es muy simple: presentar un código para extraer información de la web que no es de
fácil acceso, i.e., webs dinámicas. La cuestión era resolver un problema al que se enfrentó el informe de la
ANECA sobre editoriales de acceso abierto.
Para motivar el post nos basamos en la discusión que hay sobre las editoriales que cobran por publicar rápido
y, en particular, Sustainability, la joya de la corona de MDPI (bueno, le pisan la cola el
Applied
Sciences o el Int. J. Environ. Res. Public Health de la misma editorial, MDPI).
Antes de irme, les dejo unos datos que encontré preparando este post:
-
La Agencia Noruega de Investigación, con sólo 500 artículos publicados,
ha
decidido eliminar
Sustainability (link) de la lista de publicaciones consideradas relevantes para otorgar
méritos a los investigadores noruegos.
-
Según puede desprenderse del informe de la ANECA,
un alto porcentaje de las publicaciones en Sustainability se concentra en investigadores
pertenecientes a las áreas de Economía y Empresa.
-
Sustainability ha pasado de menos de 450 citas en 2011 a más 14.000
citas en 2021. Pero una de cada tres de las revistas en donde se cita un artículo
de Sustainability pertence a la propia MDPI (¡¡¡ que buen modelo de negocios !!!).
-
Bergstrom, se pregunta:
Why do authors publish in these venues? Some authors may be duped by spam emails, but we
suspect
that in many cases, researchers are complicit. Scientists face strong pressures to publish
frequently. With minimal or nonexistent peer review, open access publishers offer an easy route to rapid publication. The publisher may be offering authors an opportunity to
fool any bureaucracy or committee that assesses productivity by merely counting publications.
Nota: Negritas y contextualización son de los autores de este post
Esta bueno eso de fool the committee…
Código
Dejamos abajo el esquema de dos códigos: el código de gráfico inicial y la obtención de los datos de la
historia de las evaluaciones mediante Python-Selenium.
En los cursos que dictamos enseñamos los conceptos de código utilizados en este post.
Gráfico
from bs4 import BeautifulSoup
import requests
import re
from collections import defaultdict
import pandas as pd
import plotly as py
import plotly.graph_objects as go
from random import random, randrange, seed
eu_countries =(["Austria", "Belgium", "Bulgaria", "Croatia", "Cyprus", "Czech Republic",
"Denmark", "Estonia", "Finland", "France", "Germany", "Greece", "Hungary", "Ireland", "Italy", "Latvia", "Lithuania",
"Luxembourg", "Malta", "Netherlands", "Norway", "Poland", "Portugal", "Romania", "Slovakia", "Slovenia", "Spain","Sweden"]
)
eu_countries =(["Austria", "Belgium",
"Denmark", "Finland", "France", "Germany", "Greece", "Ireland", "Italy",
"Luxembourg", "Netherlands", "Norway", "Poland", "Portugal", "Spain","Sweden", "UK"]
)
dic_numero = {"pais": [], "numero_art": []}
# Itero en cada uno de los paises
for c in eu_countries:
web = f"https://www.mdpi.com/search?authors={c}&journal=sustainability&article_type=research-article"
source = requests.get(web).text
soup = BeautifulSoup(source, "lxml")
try:
n_art = soup.find(
"div", class_="content__container content__container--overflow-initial",
).text.split("\n")[2]
except:
print(f"Error:{c}")
continue
patern = r".*\(([0-9,]*)\)"
n_arts = re.search(patern, n_art).groups()[0].replace(",", "")
dic_numero["pais"].append(c)
dic_numero["numero_art"].append(int(n_arts))
print(f"pais: {c} y artículos {n_arts}")
df_articulos = pd.DataFrame(dic_numero).sort_values(by=["numero_art"], ascending=False)
# Asignar researchers por país: problema, tengo el codigo de país
# datos exctraidos de la Union Europea están con código de pais, e.g. PT
rd_pais = pd.read_csv("rd_p_persocc_page_linear.csv", sep=",")
rd_pais = rd_pais.loc[:, ["geo", "OBS_VALUE"]]
rd_pais["code"] = rd_pais["geo"]
rd_pais.set_index("code", inplace = True)
# Tengo que asignar el nombre de codigo de pais al nombre del país correspondiente
codigo_pais = pd.read_excel("codigo_pais.xls")
codigo_pais = codigo_pais.loc[:,["CODE", "COUNTRY NAME"]]
codigo_pais["codigo"] = codigo_pais["CODE"].str.strip()
codigo_pais.set_index("codigo", inplace = True)
codigo_pais.loc["DE", "COUNTRY NAME"] ="Germany"
researchers = pd.concat([codigo_pais, rd_pais], join = "inner", axis = 1)
researchers.reset_index(drop = True, inplace = True)
researchers = researchers[["COUNTRY NAME", "OBS_VALUE"]]
researchers.columns = ["pais", "pdi"]
df_datos = pd.concat([df_articulos.set_index("pais"), researchers.set_index("pais")], axis = 1, join = "inner")
df_datos["ratio"] = df_datos["numero_art"]/df_datos["pdi"]
df_datos.sort_values(by="ratio", ascending = False, inplace = True)
df_datos.reset_index(inplace = True)
# Hacemos el gráfico
color=[f'rgb({randrange(0,256)}, {randrange(0,256)},{randrange(0,256)})' for _ in range(0,df_datos.shape[0])]
fig = go.Figure()
for i in df_datos.index:
fig.add_trace(go.Scatter(
x = [df_datos.iloc[i]['pdi']],
y = [df_datos.iloc[i]['numero_art']],
mode='markers',
marker=dict(size= 450*df_datos.iloc[i]['ratio'],
color=color[i]
),
name = df_datos.iloc[i]['pais']
))
fig.update_layout(title='Sustainability: Número de publicaciones-PDI por país',
xaxis=dict(
showgrid=False,
zeroline=False,
title='Número de PDI',
#tick0=-1,
),
yaxis=dict(
showgrid=True,
zeroline=False,
title='Número de artículos',
),
font=dict(
family=" Oswald, sans-serif",
size=12,
color="gray",
)
)
fig.update_layout(
title_font_family="Oswald, sans-serif",
title_font_color="Black",
legend_title_font_color="green"
)
fig.show()
Scrapping web de historia de evaluación
Aquí se presenta la estructura básica del código, solamente extrayendo las fechas.
En el código ampliado extraemos toda la información que se quiera, i.e., títulos, autores, keywords,
abstract
etc..
import re
from time import sleep
from selenium import webdriver
from collections import defaultdict
import pandas as pd
import numpy as np
driver = webdriver.Firefox()
# Nombre de la revista
revista = "sustainability"
pais = "portugal"
num_pages = 150
# Guardamos los resultados en un diccionario
duracion = defaultdict(list)
for i in range(1, num_pages):
web_1 = f"https://www.mdpi.com/search?sort=pubdate&page_no={i}"
web_2 = (
"&page_count=10&year_from=2015&year_to=2022&authors="
+ pais
+ "&article_type=research-article&journal="
+ revista
+ "&view=compact"
)
web = web_1 + web_2
driver.get(web)
sleep(5)
try:
cookie = driver.find_element_by_xpath("/html/body/div[9]/div[3]/div[2]/a")
cookie.click()
except:
pass
# Disminuir la ventana
# driver.set_window_position(0,0)
# driver.set_window_size(480,360)
# Reducir el zoom
driver.execute_script('document.body.style.MozTransform = "scale(0.30)";')
driver.execute_script('document.body.style.MozTransformOrigin = "0 0";')
# articulo 1 -10
for j in range(1, 11):
print(j)
sleep(2.5)
titulo = driver.find_element_by_xpath(
f"/html/body/div[9]/section/div/div/div[2]/div[2]/div/div/form/div/div[2]/div[{j}]/div/a"
)
#Entro al artículo
titulo.click()
driver.execute_script('document.body.style.MozTransform = "scale(0.30)";')
driver.execute_script('document.body.style.MozTransformOrigin = "0 0";')
sleep(2.5)
# Historia del artículo
historia = driver.find_element_by_css_selector(".pubhistory").text
# Fecha en la que es recibido: importante: hay casos en los que no se explicita esta fecha
pat1 ="Received:\s([0-9 A-Z a-z]+)"
rec = re.findall(pat1, historia)
if len(rec)== 0:
rec = [np.nan]
duracion["received"] = duracion["received"] + rec
# Fechas en las que es revisado: pude haber 0 o mas revisiones
pat2 ="Revised:\s([0-9 A-Z a-z]+)"
rev = re.findall(pat2, historia)
# Numero de revisiones: no sabemos si hay artículos que son revisados más de una vez
numero_rev = len(rev)
duracion["num_revised"] = [numero_rev]
if numero_rev == 0:
duracion["revised_1"] = [np.nan]
duracion["revised_2"] = [np.nan]
duracion["revised_3"] = [np.nan]
if numero_rev == 1:
duracion["revised_1"] = duracion["revised_1"] + rev
duracion["revised_2"] = [np.nan]
duracion["revised_3"] = [np.nan]
# ACCEPTED
pat3 ="Accepted:\s([0-9 A-Z a-z]+)"
acc = re.findall(pat3, historia)
if len(acc)== 0:
acc = [np.nan]
duracion["accepted"] = duracion["accepted"] + acc
tiempo = [rec,acc]
#PUBLISHED
pat4 ="Published:\s([0-9 A-Z a-z]+)"
pub = re.findall(pat4, historia)
if len(pub)== 0:
pub = [np.nan]
duracion["published"] = duracion["published"] + pub
driver.back()
# Reducir el zoom
driver.execute_script('document.body.style.MozTransform = "scale(0.30)";')
driver.execute_script('document.body.style.MozTransformOrigin = "0 0";')
Descargo de responsabilidad: Este post ha sido escrito por Daniel Miles-Touya y lo que en el se
dice
es de su exclusiva responsabilidad. Este sitio web está destinado a un uso educativo personal y debe
emplearse únicamente con fines informativos. En consecuencia, se excluyen todas las garantías y formas de
responsabilidad derivadas del uso de este sitio web en la medida en que sean aplicables. Nada en este
sitio
web constituye una garantía de exactitud de ningún tipo -no ha habido peer review. Las llamadas de
atención
representan las opiniones personales y no pretenden ser juicios de hecho definitivos.