Este documento describe el proceso asociado al análisis bibliométrico de los manuscritos sometidos en la Revista de Informática Teórica e Aplicada (RITA).
El Dr. Márcio Dórn envió un archivo csv con los datos asociados a los artículos sometidos en RITA asociados a los años 2008 a 2022. Éstos contenían campos como ID, título, resumen e idioma, entre otros. Sin embargo, este archivo carece de otros datos relevantes, como afiliación de los autores o número de páginas de los artículos publicados.
El primer paso consistirá en limpiar los datos entregados, eliminando los campos incompletos para generar un nuevo archivo. Se eliminará también el año 2022, ya que contiene sólo unos pocos artículos.
library("stringr") #Contiene las funciones para manejo de cadenas de texto
# Lectura de datos originales
datos=read.csv("BD/Originales/articlesRITA20220520.csv",sep=",",header=T)
# Remover campos vacíos o incompletos
datos$Bio.Statement..e.g...department.and.rank...Author.25.=NULL
datos$Keywords=NULL
datos$URL=NULL
# Transformar y procesar fecha para obtener el año
idx=which(datos$Date.submitted=="")
datos=datos[-idx,]
datos$Year=as.numeric(format(as.POSIXct(datos$Date.submitted),"%Y"))
datos$Date.submitted=NULL
#Eliminar el año 2022, ya que sólo tiene dos artículos
idx=which(datos$Year==2022)
datos=datos[-idx,]
#Remover elementos que impidan guardar el archivo
library(stringr)
datos$Abstract=str_remove_all(datos$Abstract,"\n")
datos$Abstract=str_remove_all(datos$Abstract,";")
datos$Abstract=str_remove_all(datos$Abstract,"|")
datos$Abstract=str_remove_all(datos$Abstract,"\r")
#Guardar archivo
write.table(datos,file="BD/Temporales/BD1.csv",quote = F,row.names = F,sep=";")La traducción de los resúmenes en portugués al inglés podría ser realizada mediante la biblioteca googleLanguageR. Sin embargo, Google solicita una tarjeta de crédito para usar su API. Para evitar esto, el archivo BD1.csv se subirá GoogleSheets, traduciendo los resúmenes usando la función GOOGLETRANSLATE(). Como resultado se generará un archivo llamado BD2.csv.
datos=read.csv("BD/Temporales/BD2.csv",sep=",",header=T)Con el fin de extraer datos para otros análisis, como por ejemplo, afiliaciones de los autores y número de páginas, se utilizará el doi de los artículos para extraer su metadata mediante Web Scraping.
library("rvest") #Contiene las funciones para webscraping
#Sólo considerará los artículos publicados debido a que los datos de los artículos
#en revisión no están en la web
idx=which(datos$Status=="Published")
salida=NULL
contador=0
for (a in idx)
{
contador=contador+1
print(paste("Procesando",contador,"de",length(idx),sep=" "))
url=paste("http://dx.doi.org/",datos$DOI[a],sep="")
documento=read_html(url)
#listado=sort(documento %>%
# html_nodes("*") %>%
# html_attr("class") %>%
# unique())
#autores
autores=html_attr(html_nodes(documento, "meta[name=citation_author]"),'content')
#universidades
universidades=html_attr(html_nodes(documento, "meta[name=citation_author_institution]"),'content')
if (length(universidades)<length(autores)){universidades=c(universidades,rep("-",length(autores)
-length(universidades)))}
#Elimino saltos de líneas...
universidades=str_remove_all(universidades,"\n")
universidades=str_remove_all(universidades,";")
universidades=str_remove_all(universidades,"|")
universidades=str_remove_all(universidades,"\r")
#Páginas
pagina_ini=as.numeric(html_attr(html_nodes(documento, "meta[name=citation_firstpage]"),'content'))
pagina_fin=as.numeric(html_attr(html_nodes(documento, "meta[name=citation_lastpage]"),'content'))
num_paginas=pagina_fin-pagina_ini
if (length(num_paginas)==0){num_paginas=rep("-",length(autores))}
#Años
ano=datos$Year[a]
salida=rbind(salida,data.frame(doc=datos$doc[a],authors=autores,
institution=universidades,year=datos$Year[a],pages=num_paginas))
}
write.table(salida,"BD/Temporales/BD3.csv",sep=";",row.names=F,quote = F)Los datos en BD3.csv fueron procesados manualmente, normalizando el nombre de las Universidades, las ciudades en que estas se encuentran y el nombre de los autores. Estos cambios fueron almacenados como BD4.csv. Con el fin de hacer un análisis usando geolocalización, se buscarán las coordenadas (latitud y longitud) de cada ciudad almacenándose una nueva versión de los datos (BD5.csv). El código asociado es el siguiente:
datos=read.csv("BD/Temporales/BD4.csv",sep=";",header=T)
library(nominatimlite) #En reemplazo de la biblioteca de goopleMaps
ciudades=unique(datos$city)
latitud=rep("-",length(ciudades))
longitud=latitud
for (a in 1:length(ciudades))
{
print(paste("Analizando",a,"de",length(ciudades),sep=" "))
latlong=geo_lite(ciudades[a], lat="latitude", long="longitude")
latitud[a]=latlong$latitude
longitud[a]=latlong$longitude
}
datos2=data.frame(ciudades,latitud,longitud)
datos3=merge(datos,datos2,by.x = "city",by.y="ciudades")
datos3=datos3[,c(2,3,4,5,6,7,1,8,9)]
datos3$latitud[which(is.na(datos3$latitud))]="-"
datos3$longitud[which(is.na(datos3$longitud))]="-"
write.table(datos3,"BD/Finales/BD5.csv",sep=";",row.names=F,quote = F)El Dr. Márcio Dórn nos ha enviado un nuevo conjunto de datos con el número de visualizaciones de cada artículo. Estos campos serán agregadas a las base de datos (BD6.csv).
datos=read.csv("BD/Temporales/BD2.csv",sep=",",header=T)
#datos complementarios
datos_comp=read.csv("BD/Originales/views20220810.csv",sep=",",header=T)
datos=merge(datos,datos_comp[,c("Article.ID","Total.Galley.Views")],by.x = "doc",by.y="Article.ID",all = T)
names(datos)[1]="doc"
names(datos)[9]="Views"
#Remover elementos que pueden interferir en la lectura
datos$Abstract_ENG=str_remove_all(datos$Abstract_ENG,"\n")
datos$Abstract_ENG=str_remove_all(datos$Abstract_ENG,";")
datos$Abstract_ENG=str_remove_all(datos$Abstract_ENG,"|")
datos$Abstract_ENG=str_remove_all(datos$Abstract_ENG,"\r")
datos$Abstract_ENG=str_remove_all(datos$Abstract_ENG,'\"')
datos$Abstract=str_remove_all(datos$Abstract,"\n")
datos$Abstract=str_remove_all(datos$Abstract,";")
datos$Abstract=str_remove_all(datos$Abstract,"|")
datos$Abstract=str_remove_all(datos$Abstract,"\r")
datos$Abstract=str_remove_all(datos$Abstract,'\"')
#Corregir un dato erróneo
datos$Views[which(is.na(datos$Views))]="none"
#Guardar
write.table(datos,"BD/Finales/BD6.csv",sep=";",row.names=F,quote = F)Las bases de datos a utilizar sería BD5.csv y BD6.csv. La primera contiene el nombre de autores, afiliaciones y geolocalización de los artículos publicados, mientras que la segunda tiene datos generales de los artículos sometidos.
La primera pregunta a es responder es ¿Cómo ha cambiado con el tiempo el número de manuscritos y el estado de publicación?
El siguiente gráfico muestra el número de documentos sometidos y su estado para cada año.
library("ggplot2") #Gráficos
library("plotly") #Gráficos
library("dplyr") #Ordenamiento de datos
datos = read.csv("BD/Finales/BD6.csv",sep=";",header=T)
paleta = "Greens" #"Blues" "Zissou" "GrandBudapest"
#==========================================
# Shiny - Selección - Esto se debe controlar con shiny
#==========================================
#Publicados
b1=T
#Review
b2=F
#Rechazados
b3=T
datos_tmp=datos
if (b1==F){datos_tmp=datos[which(datos$Status!="Published"),]}
if (b2==F){datos_tmp=datos[which(datos$Status!="Review"),]}
if (b3==F){datos_tmp=datos[which(datos$Status!="Declined"),]}
datos_tmp= datos_tmp %>% group_by(Status,Year) %>% summarize(n())
datos_tmp=data.frame(datos_tmp)
g=ggplot(data=datos_tmp, aes(x=Year, y=n.., fill=Status)) +
geom_bar(stat="identity") +
scale_x_continuous(breaks = seq(2008, 2021, by = 1)) +
theme_classic() + xlab("years") + ylab("# Submitted manuscripts (absolute frequency)") + ylim(0,150)+
scale_fill_brewer(palette=paleta) + ggtitle("Publications by year")
ggplotly(g)El siguiente gráfico muestra el número de documentos publicados y su idioma para cada año.
#==========================================
# Shiny - Selección - Esto se debe controlar con shiny
#==========================================
#Publicados
b1=T
#Review
b2=F
#Rechazados
b3=F
datos_tmp=datos
if (b1==F){datos_tmp=datos[which(datos$Status!="Published"),]}
if (b2==F){datos_tmp=datos[which(datos$Status!="Review"),]}
if (b3==F){datos_tmp=datos[which(datos$Status!="Declined"),]}
datos_tmp=data.frame(Language=datos_tmp$Language,Year=datos_tmp$Year)
datos_tmp= datos_tmp %>% group_by(Language,Year) %>% summarize(n())
datos_tmp=data.frame(datos_tmp)
# Create the barplot
g=ggplot(data=datos_tmp, aes(x=Year, y=n.., fill=Language)) +
geom_bar(stat="identity") +
scale_x_continuous(breaks = seq(2008, 2021, by = 1)) +
theme_classic() + xlab("years") + ylab("# Submitted manuscripts (absolute frequency)") +
scale_fill_brewer(palette=paleta) + ggtitle("Submissions by year according to their language")
ggplotly(g)Esta sección aplica sobre los datos diferentes indicadores de (i) número de publicaciones, (ii) producción de autores y (iii) visitar por artículos.
Este indicador mide el porcentaje de cambio en el número de artículos entre años (Gupta and Hasan 2018). Para calcular AGR, fórmula utilizada a continuación:
\[AGR = \frac{\#Manuscripts\_year[a]-\#Manuscripts\_year[a-1]}{\#Manuscripts\_year[a-1]} \times 100 \]
#Filtro de artículos publicados
datos_tmp=datos[which(datos$Status!="Published"),]
datos_tmp=data.frame(table(datos$Year))
names(datos_tmp)[1]="Years"
datos_tmp$Freq_AC=cumsum(datos_tmp$Freq)
#Cálculo de ARG
ARG=rep(0,nrow(datos_tmp))
for (a in 2:nrow(datos_tmp))
{ARG[a]=round(((datos_tmp$Freq[a]-datos_tmp$Freq[a-1])/datos_tmp$Freq[a-1])*100,2)}
datos_tmp$AGR=ARGCorresponde a la tasa de crecimiento acumulado del número de publicaciones durante un período de tiempo específico (Kulkanjanapiban and Silwattananusarn 2021). Ésta se calcula como:
\[CAGR = {(\frac{\#Manuscripts\_year_{CUM}[a]}{\#Manuscripts\_year_[a]}}^{\frac{1}{(year[a])}} - 1) \times 100\]
#Cálculo CARG
carg = rep(0,nrow(datos_tmp))
for (a in 2:nrow(datos_tmp))
{carg[a]=((datos_tmp$Freq_AC[a]/datos_tmp$Freq[a])^(1/(a-1)))-1}
datos_tmp$CARG = (round(carg,4)*100)Corresponde al aumento del número de artículos publicado por unidad de tiempo (Kumar and Kaliyaperumal 2015) (Rathika and Thanuskodi 2021). El RGR promedio para un intervalo de tiempo puede calcularse usando:
\[RGR = 1-2^R = {\frac{ln{(\#Manuscripts\_year_{CUM}[a])}-ln{(\#Manuscripts\_year_{CUM}[a-1])}}{year[a]-year[a-1]}}\]
#Cálculo de RGR
RGR = rep(0,nrow(datos_tmp))
for (a in 2:nrow(datos_tmp))
{RGR[a]=log(datos_tmp$Freq_AC[a])-log(datos_tmp$Freq_AC[a-1])}
datos_tmp$RGR = round(RGR,2)Existe una relación directa entre RGR y el tiempo que tardaría el número de publicaciones en duplicarse. Para calcular el tiempo de duplicación (DT) se utiliza aquí un logaritmo natural estándar de 0,693 (Kumar and Kaliyaperumal 2015) (Rathika and Thanuskodi 2021), aplicando la siguiente ecuación:
\[DT = \frac{0.693}{RGR} \]
#Cálculo de DT
datos_tmp$DT = round(0.603/datos_tmp$RGR,2)
datos_tmp$DT[1]=0El resultado de los indicadores es el siguiente:
knitr::kable(datos_tmp[,c(1:7)])| Years | Freq | Freq_AC | AGR | CARG | RGR | DT |
|---|---|---|---|---|---|---|
| 2008 | 58 | 58 | 0.00 | 0.00 | 0.00 | 0.00 |
| 2009 | 78 | 136 | 34.48 | 74.36 | 0.85 | 0.71 |
| 2010 | 74 | 210 | -5.13 | 68.46 | 0.43 | 1.40 |
| 2011 | 52 | 262 | -29.73 | 71.43 | 0.22 | 2.74 |
| 2012 | 85 | 347 | 63.46 | 42.14 | 0.28 | 2.15 |
| 2013 | 53 | 400 | -37.65 | 49.82 | 0.14 | 4.31 |
| 2014 | 70 | 470 | 32.08 | 37.35 | 0.16 | 3.77 |
| 2015 | 76 | 546 | 8.57 | 32.54 | 0.15 | 4.02 |
| 2016 | 65 | 611 | -14.47 | 32.32 | 0.11 | 5.48 |
| 2017 | 80 | 691 | 23.08 | 27.07 | 0.12 | 5.03 |
| 2018 | 127 | 818 | 58.75 | 20.47 | 0.17 | 3.55 |
| 2019 | 75 | 893 | -40.94 | 25.26 | 0.09 | 6.70 |
| 2020 | 53 | 946 | -29.33 | 27.15 | 0.06 | 10.05 |
| 2021 | 51 | 997 | -3.77 | 25.69 | 0.05 | 12.06 |
Se define como la relación entre el artículos con más de un autor (\(N_m\)) y los escritos por sólo una persona (\(N_s\)) (Savanur and Srikanth 2009) (Gupta and Hasan 2018) (Barik and Jena 2019) (Das, Kaur, and Verma 2021).
\[DC = \frac{N_m}{N_m+N_s}\]
DC= rep(0,length(anos))
for (a in 1:length(anos))
{tmp=datos_tmp2[which(datos_tmp2$year==anos[a]),]
N_m = length(which(tmp$Freq>1))
N_s = length(which(tmp$Freq==1))
DC[a] = round(N_m/(N_m+N_s),2)
}
datos_tmp$DC = DCEs un promedio ponderado de autores por artículo conjunto. Es decir aquellos que tienen más de un autor(Savanur and Srikanth 2009) (Gupta and Hasan 2018) (Barik and Jena 2019) (Das, Kaur, and Verma 2021).
\[CI=\frac{\sum_{j=1}^{A}{j \times f_j}}{N}\]
Donde:
CI= rep(0,length(anos))
for (a in 1:length(anos))
{
#Denominador
tmp=datos_tmp2[which(datos_tmp2$year==anos[a]),]
deno=length(tmp$Freq)
#Numerador
A = max(tmp$Freq)
nume = 0
for (j in 1:A)
{ nume = nume + j*length(which(tmp$Freq==j))}
CI[a]=round(nume/deno,2)
}
datos_tmp$CI = CIEste indicador se aplica y describe en (Savanur and Srikanth 2009) (Barik and Jena 2019) (Das, Kaur, and Verma 2021).
\[CC=1-\frac{\sum_{j=1}^{A}{ \frac{1}{j} \times f_j}}{N}\]
Donde:
CC= rep(0,length(anos))
for (a in 1:length(anos))
{
#Denominador
tmp=datos_tmp2[which(datos_tmp2$year==anos[a]),]
deno=length(tmp$Freq)
#Numerador
A = max(tmp$Freq)
nume = 0
for (j in 1:A)
{ nume = nume + (1/j)*length(which(tmp$Freq==j))}
CC[a]=round(1-(nume/deno),2)
}
datos_tmp$CC = CCEste indicador se aplica y describe en (Das, Kaur, and Verma 2021).
\[MCC=(\frac{N}{N-1})(1-\frac{\sum_{j=1}^{A}{ \frac{1}{j} \times f_j}}{N})\]
Donde:
MCC= rep(0,length(anos))
for (a in 1:length(anos))
{
#Denominador
tmp=datos_tmp2[which(datos_tmp2$year==anos[a]),]
deno=length(tmp$Freq)
#Numerador
A = max(tmp$Freq)
nume = 0
for (j in 1:A)
{ nume = nume + (1/j)*length(which(tmp$Freq==j))}
MCC[a]=round((deno/(deno-1))*(1-(nume/deno)),2)
}
datos_tmp$MCC = MCCCorresponde al promedio de páginas por artículo publicado.
\[ PNA = \frac{\sum\mbox{#Page number}}{\mbox{#Manuscript by year}}\]
datos = read.csv("BD/Finales/BD5.csv",sep=";",header=T)
anos = unique(datos$year)
PNA = rep(0,length(anos))
for (a in 1:length(anos))
{ deno=length(which(datos$year==anos[a]))
pag = datos$pages[which(datos$year==anos[a])]
pag = pag[which(pag!="-")]
nume=sum(as.numeric(pag))
PNA[a] = nume/deno
}
datos_tmp$PNA = round(PNA,2)Los indicadores de producción asociados a los autores serían los siguientes:
knitr::kable(datos_tmp[,c(1,2,8:14)])| Years | Freq | AAPP | PPAA | DC | CI | CC | MCC | PNA |
|---|---|---|---|---|---|---|---|---|
| 2008 | 58 | 2.04 | 0.49 | 0.80 | 2.38 | 0.48 | 0.49 | 9.75 |
| 2009 | 78 | 3.38 | 0.30 | 1.00 | 3.56 | 0.68 | 0.70 | 20.16 |
| 2010 | 74 | 3.55 | 0.28 | 0.95 | 3.89 | 0.65 | 0.67 | 14.15 |
| 2011 | 52 | 3.20 | 0.31 | 1.00 | 3.20 | 0.64 | 0.71 | 12.29 |
| 2012 | 85 | 2.84 | 0.35 | 0.96 | 2.96 | 0.62 | 0.64 | 22.33 |
| 2013 | 53 | 2.43 | 0.41 | 0.86 | 2.50 | 0.53 | 0.57 | 23.33 |
| 2014 | 70 | 2.94 | 0.34 | 0.94 | 3.06 | 0.61 | 0.65 | 23.99 |
| 2015 | 76 | 3.12 | 0.32 | 0.96 | 3.16 | 0.64 | 0.66 | 23.96 |
| 2016 | 65 | 3.38 | 0.30 | 0.92 | 3.46 | 0.64 | 0.69 | 21.51 |
| 2017 | 80 | 2.90 | 0.34 | 0.95 | 2.90 | 0.60 | 0.63 | 14.71 |
| 2018 | 127 | 3.03 | 0.33 | 0.94 | 3.12 | 0.61 | 0.63 | 13.39 |
| 2019 | 75 | 3.42 | 0.29 | 0.88 | 3.58 | 0.62 | 0.65 | 13.17 |
| 2020 | 53 | 2.58 | 0.39 | 0.88 | 2.58 | 0.54 | 0.56 | 19.38 |
| 2021 | 51 | 3.21 | 0.31 | 1.00 | 3.29 | 0.64 | 0.69 | 17.92 |
\[VPA = \frac{\mbox{#Views by year}}{\mbox{#Manuscript by year}}\]
datos = read.csv("BD/Finales/BD6.csv",sep=";",header=T)
datos = datos[which(datos$Status=="Published"),]
anos = unique(datos$Year)
VPA= rep(0,length(anos))
for(a in 1:length(anos))
{ tmp=datos[which(datos$Year==anos[a]),]
views=tmp$Views[which(tmp$Views!="none")]
VPA[a] = mean(as.numeric(tmp$Views))
}
datos_tmp$VPA = round(VPA,2)\[ VAPA = \frac{\frac{\mbox{#Views by year}}{\mbox{#Manuscript by year}}}{(Final_{year} - Current_{year} + 1)}\]
VAPA= rep(0,length(anos))
for (a in 1:length(anos))
{ deno=anos[length(anos)]-anos[a]+1
VAPA[a] = datos_tmp$VPA[a]/deno
}
datos_tmp$VAPA = round(VAPA,2)El resultado de estos indicadores sería el siguiente:
knitr::kable(datos_tmp[,c(1,2,15,16)])| Years | Freq | VPA | VAPA |
|---|---|---|---|
| 2008 | 58 | 3019.20 | 215.66 |
| 2009 | 78 | 2178.62 | 167.59 |
| 2010 | 74 | 1375.89 | 114.66 |
| 2011 | 52 | 2804.50 | 254.95 |
| 2012 | 85 | 1154.80 | 115.48 |
| 2013 | 53 | 1458.00 | 162.00 |
| 2014 | 70 | 1599.75 | 199.97 |
| 2015 | 76 | 1804.76 | 257.82 |
| 2016 | 65 | 3079.08 | 513.18 |
| 2017 | 80 | 1101.70 | 220.34 |
| 2018 | 127 | 881.97 | 220.49 |
| 2019 | 75 | 708.38 | 236.13 |
| 2020 | 53 | 659.50 | 329.75 |
| 2021 | 51 | 224.93 | 224.93 |
En esta sección se calcula el promedio de algunos indicadores para todo el histórico de la revista y se efectúa una prueba de contraste hipótesis para una muestra, para ver si esta media es significativa.
El promedio de publicaciones es 71.21, con una desviación estándar de 19.86. El resultado de la prueba de contraste es la siguiente:
#wilcox.test(x=datos_tmp$Freq,mu=mean(datos_tmp$Freq),alternative="two.sided")
t.test(x=datos_tmp$Freq,mu=mean(datos_tmp$Freq),alternative="two.sided")##
## One Sample t-test
##
## data: datos_tmp$Freq
## t = 0, df = 13, p-value = 1
## alternative hypothesis: true mean is not equal to 71.21429
## 95 percent confidence interval:
## 59.74869 82.67988
## sample estimates:
## mean of x
## 71.21429
Cargaremos los datos..
datos = read.csv("BD/Finales/BD5.csv",sep=";",header=T)
pag = as.numeric(datos$pages[which(datos$pages!="-")])El promedio de páginas por publicación es 16.96, con una desviación estándar de 9.15. El resultado de la prueba de contraste es la siguiente:
print(mean(pag))## [1] 16.96353
t.test(x=pag,mu=mean(pag),alternative="two.sided")##
## One Sample t-test
##
## data: pag
## t = 0, df = 1041, p-value = 1
## alternative hypothesis: true mean is not equal to 16.96353
## 95 percent confidence interval:
## 16.40751 17.51956
## sample estimates:
## mean of x
## 16.96353
Cargaremos los datos..
datos = read.csv("BD/Finales/BD6.csv",sep=";",header=T)
views = as.numeric(datos$Views[which(datos$Views!="none")])
views = views/(max(datos$Year)-datos$Year[which(datos$Views!="none")]+1)El promedio de visualizaciones por publicación es 215.91, con una desviación estándar de 345.33. El resultado de la prueba de contraste es la siguiente:
t.test(x=views,mu=mean(views),alternative="two.sided")##
## One Sample t-test
##
## data: views
## t = 0, df = 334, p-value = 1
## alternative hypothesis: true mean is not equal to 215.9125
## 95 percent confidence interval:
## 178.799 253.026
## sample estimates:
## mean of x
## 215.9125
La segunda pregunta a es responder es ¿Cómo han evolucionado las áreas de conocimiento asociadas a los manuscritos?
En esta sección se estudiarán las palabras claves que permiten caracterizar la producción de cada año, basándose en los resúmenes de cada artículo publicado y el Tesauro desarrollado por IEEE.
El primer paso consistirá en cargar las bibliotecas asociadas a procesamiento de lenguaje natural.
#Bibliotecas
library("quanteda")
library("quanteda.textplots")
library("quanteda.corpora")
library("quanteda.textmodels")
library("quanteda.textstats")
library("quanteda.textplots")
library("stringr")
library("lubridate")Posteriormente se buscarán en el resumen sólo las palabras asociadas al tesauro IEEE y se aplicará la prueba Chi-squares para identificar las áreas y subáreas que caracterizan a cada año, o su acumulado, respecto a los periodos restantes.
#Bibliotecas
library("quanteda")
library("quanteda.textplots")
library("quanteda.corpora")
library("quanteda.textmodels")
library("quanteda.textstats")
library("quanteda.textplots")
library("stringr")
library("lubridate")
#Lectura de datos
#Datos originales
datos=read.csv("BD/Finales/BD6.csv",sep=";",header=T)
#Tesauro
thesaurus=read.csv("BD/Originales/IEEE_tesauro.csv",sep=";",header = T)
thesaurus_subareas=unique(thesaurus$Area4)
#Filtrado de datos publicados
datos=datos[which(datos$Status=="Published"),]
#Creación del corpus: los datos son convertidos a formato de corpus
corpus_datos = corpus(datos, text_field = "Abstract_ENG")
#summary(corpus_datos,5)
#Tokenizatión: los datos son tokenizados, estandarizando el texto
toks_datos = tokens(corpus_datos,remove_punct = T,remove_symbols = T, remove_numbers = T, remove_url = T,
remove_separators = T)
#Convertir mayúsculas a minúsculas
toks_datos=tokens_tolower(toks_datos)
#Filtramos del tokenizado sólos las palabras similares a las subáreas del tesauro
kw_datos = kwic(toks_datos, pattern = phrase(thesaurus_subareas))
#Nos quedamos sólo con los elementos relevantes
kw_datos$from=kw_datos$from=kw_datos$to=kw_datos$pre=kw_datos$post=kw_datos$pattern=NULL
#Le agregamos a kw_datos los años
corpus_organizado=summary(corpus_datos,n=length(kw_datos$docname))
kw_datos=merge(kw_datos,corpus_organizado[,c("Text","Year")],by.x="docname",by.y = "Text")
#Transfomación de kw en corpus
corpus_kw = corpus(kw_datos,text_field="keyword")
toks_datos_the = tokens(corpus_kw)
toks_datos_the = tokens_compound(toks_datos_the, pattern = phrase(thesaurus_subareas))
dfmat_datos_the = dfm(toks_datos_the)
#=========================================================================================================
# Esto está pensado para Shiny, debe ser capaz además de considerar el acumulado por año, hasta el 2020
#=========================================================================================================
ano="2021"
acumulado=F #En este caso sólo puede llegar al 2020
#Graficar
if (acumulado==F){tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Year == ano)} else
{tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Year <= ano)}
grafico_sub_areas=textplot_keyness(tstat_key,labelsize = 4,n=10,margin = 0.6,
color = c("mediumaquamarine", "gray"))
#Areas
thesaurus$Area4=tolower(thesaurus$Area4)
kw_datos2=merge(kw_datos,thesaurus[,c("Area2","Area4")],by.x="keyword",by.y="Area4")
corpus_kw = corpus(kw_datos2,text_field="Area2")
toks_datos_the = tokens(corpus_kw,remove_punct = T,remove_symbols = T, remove_numbers = T, remove_url = T,
remove_separators = T)
toks_datos_the = tokens_compound(toks_datos_the, pattern = phrase(thesaurus$Area2))
dfmat_datos_the = dfm(toks_datos_the)
#Graficar
if (acumulado==F) {tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Year == ano)} else
{tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Year <= ano)}
grafico_areas=textplot_keyness(tstat_key,labelsize = 4,n=10,margin = 0.6,
color = c("mediumaquamarine", "gray"))plot(grafico_areas)plot(grafico_sub_areas)
La tercera pregunta a es responder es ¿Cuáles son las principales características de los autores que publicar en la revista en términos de frecuencia, institución, país y colaboración?
Esta sección busca identificar cuáles son los autores y universidades que más publican, efectuando una representación geográfica.
Los autores que más han publicado son los siguientes:
datos=read.csv("BD/Finales/BD5.csv", sep=";",header = T)
datos2=read.csv("BD/Finales/BD6.csv", sep=";",header = T)
datos=merge(datos,datos2[,c("doc","Status")],by="doc")
datos=datos[which(datos$Status=="Published"),]
#=========================================================================================================
# Esto está pensado para Shiny, debe ser capaz además de considerar el acumulado por año
#=========================================================================================================
#Filtro por año. También debe incluir la opción ALL
ano="2021"
acumulado = F
if (acumulado==F) {datos=datos[which(datos$year==ano),]} else
{datos=datos[which(datos$year<=ano),]}
autores=data.frame(table(datos$authors))
autores=autores[order(autores$Freq,decreasing = T),]
rownames(autores)=NULL
names(autores)=c("Autores","Frec")
knitr::kable(head(autores,10))| Autores | Frec |
|---|---|
| Eanes Torres Pereira | 2 |
| Anderson Fernandes Pereira dos Santos | 1 |
| André Augusto Kaviatkovski | 1 |
| Andre Pinz Borges | 1 |
| Carlos Eduardo Pantoja | 1 |
| Carlos Raimundo Erig Lima | 1 |
| Cesar Augusto Borges | 1 |
| Cesar Augusto Tacla | 1 |
| Claudia Bauzer Medeiros | 1 |
| Cleyton Ferreira Gonçalves | 1 |
El siguiente grafo muestra las relaciones entre autores para el mismo periodo de tiempo:
library("igraph")
library("networkD3")
documentos=unique(datos$doc)
autores=sort(unique(datos$authors))
matriz_autores=matrix(0,ncol=length(autores),nrow=length(autores))
rownames(matriz_autores)=colnames(matriz_autores)=autores
for (a in 1:length(autores))
{ idx=datos$authors[which(datos$doc==documentos[a])]
matriz_autores[idx,idx]=matriz_autores[idx,idx]+1
}
for (a in 1:length(autores))
{matriz_autores[a,a]=0}
g1 = graph_from_adjacency_matrix(matriz_autores,weighted=T,mode="directed")
simpleNetwork(as_data_frame(g1),zoom=T,linkDistance = 30)Las instituciones que más han publicado son las siguientes:
instituciones=datos$norm_institution[which(datos$norm_institution!="-")]
instituciones=data.frame(table(instituciones))
instituciones=instituciones[order(instituciones$Freq,decreasing = T),]
rownames(instituciones)=NULL
names(instituciones)=c("Instituciones","Frec")
knitr::kable(head(instituciones,10))| Instituciones | Frec |
|---|---|
| Universidade Tecnológica Federal do Paraná | 9 |
| Universidade Estadual de Campinas | 4 |
| Universidade Federal de Campina Grande | 4 |
| CTI Renato | 3 |
| Universidade Federal Rural de Pernambuco | 3 |
| Instituto Federal do Maranhão | 2 |
| Instituto Militar de Engenharia | 2 |
| Systems Development Center (CDS) | 2 |
| Universidade de São Paulo | 2 |
| Centro Universitário Campo Limpo Paulista | 1 |
El siguiente grafo muestra las relaciones entre instituciones para el mismo periodo de tiempo:
norm_institution=sort(unique(datos$norm_institution))
matriz_institution=matrix(0,ncol=length(norm_institution),nrow=length(norm_institution))
rownames(matriz_institution)=colnames(matriz_institution)=norm_institution
for (a in 1:length(norm_institution))
{ idx=datos$norm_institution[which(datos$doc==documentos[a])]
matriz_institution[idx,idx]=matriz_institution[idx,idx]+1
}
for (a in 1:length(norm_institution))
{matriz_institution[a,a]=0}
g1 = graph_from_adjacency_matrix(matriz_institution,weighted=T,mode="directed")
simpleNetwork(as_data_frame(g1),zoom=T,linkDistance = 30)Esta sección intenta ubicar las ciudades asociadas a las universidades que publican y sus relaciones.
library(tidyverse)
library(leaflet)
library(sf)
library(geosphere)
datos=read.csv("BD/Finales/BD5.csv", sep=";",header = T)
datos2=read.csv("BD/Finales/BD6.csv", sep=";",header = T)
datos2=merge(datos,datos2[,c("doc","Status")],by="doc")
if (length(which(datos$city=="-")>0))
{datos2=datos[-which(datos$city=="-"),]} else
{datos2=datos}
#=========================================================================================================
# Esto está pensado para Shiny, debe ser capaz además de considerar el acumulado por año
#=========================================================================================================
if (acumulado==F){datos2=datos2[datos2$year==ano,]} else
{datos2=datos2[datos2$year<=ano,]}
datos2=data.frame(table(datos2$city))
names(datos2)=c("ciudad","autores")
datos3=unique(merge(datos2,datos[,c("city","latitud","longitud")],by.x="ciudad",by.y="city"))
m = leaflet()
m = setView(m,-14, 10, zoom = 2)
m = addProviderTiles(m,providers$CartoDB.Positron,
options = providerTileOptions(minZoom = 2, maxZoom = 10))
m = addCircleMarkers(m, lat = as.numeric(datos3$latitud),lng = as.numeric(datos3$longitud),
radius = (datos3$autores)*0.3,
stroke = T,
color = "darkgreen",
opacity = 0.2)
datos4=unique(merge(datos2,datos[,c("doc","city","latitud","longitud")],by.x="ciudad",by.y="city"))
documentos=unique(datos4$doc)
longitudes=NULL
latitudes=NULL
for (a in 1:length(documentos))
{
datos4_tmp=datos4[which(datos4$doc==documentos[a]),]
for (b in 1:(nrow(datos4_tmp)-1))
{
if (nrow(datos4_tmp)>1)
{latitudes=rbind(latitudes,datos4_tmp$latitud[c(b,b+1)])
longitudes=rbind(longitudes,datos4_tmp$longitud[c(b,b+1)])
}
}
}
m=addPolylines(m,lng=as.numeric(longitudes), lat=as.numeric(latitudes), color="darkgreen", weight=2,opacity=0.2,stroke = T)
m = setMaxBounds(m, lng1 = -200
, lat1 = -80
, lng2 = 200
, lat2 = 80 )
m
La tercera pregunta a es responder es ¿Cuáles son las principales características de los manuscritos rechazados?. En este caso sólo disponemos de los abstracts, por lo que se procederá a estudiar las áreas del conocimiento que diferencian los artículos rechazados de los publicados.
#Lectura de datos
#Datos originales
datos=read.csv("BD/Finales/BD6.csv",sep=";",header=T)
#Tesauro
thesaurus=read.csv("BD/Originales/IEEE_tesauro.csv",sep=";",header = T)
thesaurus_subareas=unique(thesaurus$Area4)
#=========================================================================================================
# Esto está pensado para Shiny, debe ser capaz además de considerar el acumulado por año
#=========================================================================================================
ano= "2021"
acumulado = F
if (acumulado==F){datos=datos[which(datos$Year==ano),]} else
{datos=datos[which(datos$Year<=ano),]}
#Creación del corpus: los datos son convertidos a formato de corpus
corpus_datos = corpus(datos, text_field = "Abstract_ENG")
#summary(corpus_datos,5)
#Tokenizatión: los datos son tokenizados, estandarizando el texto
toks_datos = tokens(corpus_datos,remove_punct = T,remove_symbols = T, remove_numbers = T, remove_url = T,
remove_separators = T)
#Convertir mayúsculas a minúsculas
toks_datos=tokens_tolower(toks_datos)
#Filtramos del tokenizado sólos las palabras similares a las subáreas del tesauro
kw_datos = kwic(toks_datos, pattern = phrase(thesaurus_subareas))
#Nos quedamos sólo con los elementos relevantes
kw_datos$from=kw_datos$from=kw_datos$to=kw_datos$pre=kw_datos$post=kw_datos$pattern=NULL
#Le agregamos a kw_datos los años
corpus_organizado=summary(corpus_datos,n=length(kw_datos$docname))
kw_datos=merge(kw_datos,corpus_organizado[,c("Text","Status")],by.x="docname",by.y = "Text")
#Transfomación de kw en corpus
corpus_kw = corpus(kw_datos,text_field="keyword")
toks_datos_the = tokens(corpus_kw)
toks_datos_the = tokens_compound(toks_datos_the, pattern = phrase(thesaurus_subareas))
dfmat_datos_the = dfm(toks_datos_the)
#=========================================================================================================
# Esto está pensado para Shiny, debe ser capaz además de considerar el acumulado por año
#=========================================================================================================
#Graficar
tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Status != "Published")
grafico_sub_areas=textplot_keyness(tstat_key,labelsize = 4,n=10,margin = 0.6,
color = c("mediumaquamarine", "gray"))
#Areas
thesaurus$Area4=tolower(thesaurus$Area4)
kw_datos2=merge(kw_datos,thesaurus[,c("Area2","Area4")],by.x="keyword",by.y="Area4")
corpus_kw = corpus(kw_datos2,text_field="Area2")
toks_datos_the = tokens(corpus_kw,remove_punct = T,remove_symbols = T, remove_numbers = T, remove_url = T,
remove_separators = T)
toks_datos_the = tokens_compound(toks_datos_the, pattern = phrase(thesaurus$Area2))
dfmat_datos_the = dfm(toks_datos_the)
#Graficar
tstat_key = textstat_keyness(dfmat_datos_the,target = dfmat_datos_the$Status != "Published")
grafico_areas=textplot_keyness(tstat_key,labelsize = 4,n=10,margin = 0.6,
color = c("mediumaquamarine", "gray"))plot(grafico_areas)plot(grafico_sub_areas)