[{"content":"Motivación Creo que la discusión más común en los equipos de ciencia de datos es R vs Python. Me he visto en algunas de estas discusiones un par de veces y mi posición es siempre \u0026ldquo;¿Por qué no usar ambos?\u0026rdquo;. La idea de este post no es comparar R vs Python, sino mostrar lo fácil que es integrar ambos lenguajes usando APIs (COMO UN PROFESIONAL); de esta manera podemos usar lo mejor de cada uno. Además, el post no se centrará en la publicación y la estructura necesarias para poner las APIs en línea; en su lugar, lo demostraré localmente (para que sea simple).\nEste post está dividido en 3 secciones: Crear una función, Crear una API y Llamar a una API. En la primera sección encontrarás una función simple creada en R y Python; la segunda sección trata sobre cómo transformar esas funciones en APIs; la última es cómo podemos llamar/usar las APIs.\nCrear una función Imagina que trabajas en un equipo de ciencia de datos y alguien necesita un código que devuelva la suma de dos valores (perdón por el ejemplo tonto). Mira, la solicitud no es sobre R, Python, Julia, Java o lo que sea, sino sobre resolver el problema. Entonces, resolvamos el problema de la mejor manera que podamos y escribamos una función para resolverlo en R y Python.\nEste post no cubrirá las pautas para crear funciones útiles. Para eso te recomiendo echar un vistazo a la sección Functions del Advanced R Book.\nFunción en R Una función simple para devolver la suma de dos valores en R se vería así:\nsum_two_r \u0026lt;- function(x, y) { result \u0026lt;- x + y return(result) } Listo, ahora podemos llamarla dentro de R así:\nsum_two_r(x = 1, y = 1) ## [1] 2 Función en Python Una función simple para devolver la suma de dos valores en Python se vería así:\ndef sum_two_python(x, y): result = x + y return result Listo, ahora podemos llamarla dentro de Python así:\nsum_two_python(x = 1, y = 1) ## 2 Crear una API El problema está casi resuelto, pero todavía necesitamos encontrar la mejor manera de compartir nuestra solución con el resto del equipo. Bueno, la parte del equipo que trabaja en R puede usar la función que escribimos en R, pero esa función simplemente no está disponible para la parte del equipo que usa Python; lo mismo ocurre con el código escrito en Python, que simplemente no está disponible para nadie que use R. Entonces, es necesario crear una solución independiente del lenguaje para que sea accesible para todos en el equipo.\nSé que el paquete reticulate puede ayudar, pero es una solución de un solo sentido, y nos interesa una forma más genérica de integración que pueda extenderse no solo a Python, sino a cualquier lenguaje de programación.\nUna buena solución sería crear y publicar una API con nuestro código; de esta manera el resto del equipo puede interactuar con ella de forma independiente; en otras palabras, ya no importa cuál fue el lenguaje que usaste para resolver el problema. Para ello vamos a usar el paquete plumber para R y el paquete FastAPI para Python.\nEste post no cubrirá cómo publicar las APIs. Sin embargo, si estás interesado en aprender cómo poner tus APIs en línea, puedes usar este enlace para plumber y este enlace para FastAPI.\nAPI en R El primer paso para crear una API en R es instalar el paquete plumber:\ninstall.packages(\u0026#34;plumber\u0026#34;) Hecho eso, volvamos a nuestro archivo de funciones y agreguemos un par de cosas.\n#* @param x first number #* @param y second number #* @get /sum_r sum_two_r \u0026lt;- function(x, y) { result \u0026lt;- as.numeric(x) + as.numeric(y) return(result) } Nota que agregamos algunos \u0026ldquo;comentarios\u0026rdquo; al inicio del código muy similares a los usados en el paquete roxygen2. Estos comentarios son la clave que usa plumber para transformar tus funciones en endpoints de APIs. Además, para este ejemplo definimos una solicitud GET; lo mismo podría hacerse, por ejemplo, con solicitudes POST cambiando el comentario a #* @post /sum_r.\nSi no estás familiarizado con las solicitudes HTTP, puedes echar un vistazo a este enlace.\nPuedes ver que se incluyó la transformación as.numeric(), que es necesaria porque los parámetros \u0026ldquo;entran\u0026rdquo; a R como strings, y para aplicar operaciones matemáticas es necesario transformar los numéricos en números.\nEl siguiente paso es publicarla. Para ponerla en línea solo necesitas proporcionar la ruta del archivo y el puerto en el que quieres exponer la API. La pondremos disponible localmente (localhost) en el puerto 8000 ejecutando:\nlibrary(magrittr) library(plumber) pr(\u0026#39;functions/sum_r.R\u0026#39;) %\u0026gt;% pr_run(port = 8000) ¡Listo! Ahora nuestra API está expuesta y puedes acceder a la documentación Swagger en http://localhost:8000/docs/, e interactuar con ella presionando GET, seguido del botón Try it out, completar los parámetros y presionar Execute.\nSi quieres aprender más sobre Swagger UI, aquí tienes el enlace.\n$ pip install fastapi[all] Hecho eso, volvamos a nuestro archivo de funciones y agreguemos un par de cosas.\nfrom fastapi import FastAPI app = FastAPI() @app.get(\u0026#34;/sum_py\u0026#34;) def sum_two_python(x:float, y:float): result = x + y return result Nota que importamos el paquete fastapi y creamos un objeto llamado app que es una instancia de FastAPI. Luego lo definimos como una solicitud GET; lo mismo podría hacerse, por ejemplo, con solicitudes POST cambiando a @app.post(\u0026quot;/sum_py\u0026quot;).\nPuedes ver que se incluyó el :float para forzar que el tipo de variable sea numérico; eso es necesario porque las llamadas de API predeterminadas \u0026ldquo;entran\u0026rdquo; a Python como strings, y para aplicar operaciones matemáticas es necesario transformar los numéricos en números.\nEl siguiente paso es publicarla. Para ponerla en línea solo necesitas abrir la terminal y entrar dentro de la carpeta donde guardaste tu script de API en Python. Nombré mi archivo como \u0026ldquo;sum_py\u0026rdquo; y lo pondré disponible localmente (localhost) en el puerto 8080 ejecutando:\n$ uvicorn sum_py:app --port 8080 --reload La opción reload recargará tu API cada vez que guardes el archivo. ¡Es una muy buena función para el desarrollo!\n¡Listo! Ahora nuestra API está expuesta y puedes acceder a la documentación Swagger en http://localhost:8080/docs#/, e interactuar con ella presionando GET, seguido del botón Try it out, completar los parámetros y presionar Execute.\nPor supuesto, en el mundo real la publicación de tus APIs no debería ser local, pero la lógica será (casi) la misma. Además, hay MUCHAS MÁS FUNCIONES en el desarrollo de APIs, así que mi consejo sería leer la documentación de plumber y FastAPI para aprender más al respecto.\ninstall.packages(\u0026#34;httr\u0026#34;) ¿Recuerdas que nuestra API de Python se está ejecutando localmente (localhost) en el puerto 8080? Bueno, eso y el tipo de solicitud (GET, en este caso) son la única información que necesitamos para llamarla desde R.\nlibrary(httr) python_request \u0026lt;- GET(\u0026#39;http://localhost:8080/sum_py?x=1\u0026amp;y=1\u0026#39;) python_result \u0026lt;- content(python_request) python_result ## [1] 2 Llamar a una API en Python Hagamos lo mismo, pero esta vez vamos a llamar a la API de R desde Python. Para ello será necesario instalar el paquete requests.\n$ pip install requests Nuestra API de R también se está ejecutando en localhost, pero en el puerto 8000. De nuevo, eso y el tipo de solicitud (GET, en este caso) son la única información que necesitamos para llamarla desde Python.\nimport requests r_request = requests.get(\u0026#34;http://localhost:8000/sum_r?x=1\u0026amp;y=1\u0026#34;) print(r_request.json()) ## [2] Eso es todo Hay MUCHO MÁS que discutir cuando hablamos de APIs/publicación/llamadas/solicitudes, pero la idea era hacerlo simple, demostrar las posibilidades y DETENER LA PELEA entre R y Python 😆. Creo que este post es un buen ejemplo de cómo integrar ambos lenguajes (COMO UN PROFESIONAL), porque, al final, queremos RESOLVER EL PROBLEMA!!! ¿Realmente importa si lo resolviste en Python o R?\nEspero que alguien encuentre esto útil. Como siempre, tus comentarios son muy apreciados; ¡no dudes en ponerte en contacto conmigo a través de las redes sociales! 😄\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/why-not-both/","summary":"\u003ch2 id=\"motivación\"\u003eMotivación\u003c/h2\u003e\n\u003cp\u003eCreo que la discusión más común en los equipos de ciencia de datos es R vs Python. Me he visto en algunas de estas discusiones un par de veces y mi posición es siempre \u0026ldquo;\u003cem\u003e¿Por qué no usar ambos?\u003c/em\u003e\u0026rdquo;. La idea de este post no es comparar R vs Python, sino mostrar lo fácil que es \u003cstrong\u003eintegrar ambos lenguajes usando APIs\u003c/strong\u003e (COMO UN PROFESIONAL); de esta manera podemos usar lo mejor de cada uno. Además, el post no se centrará en la publicación y la estructura necesarias para poner las APIs en línea; en su lugar, lo demostraré localmente (para que sea simple).\u003c/p\u003e","title":"¿Por qué no ambos?"},{"content":"Motivación Recientemente algunos amigos me presentaron GitHub Actions y cómo podría ayudarme a ejecutar tareas como: publicar mis Shiny Apps, publicar este Blogdown, realizar pruebas automáticas en paquetes, actualizar datos y más. Así que decidí probarlo, y fue tan simple y me ahorró tantas horas de trabajo que decidí escribir este post explicando cómo los desarrolladores de R pueden hacer buen uso de esta increíble herramienta.\nPrimero, las referencias que usé para empezar con GitHub Actions:\nLa presentación de Jim Hester en la RStudio Conference aquí.\nEl repositorio de GitHub Actions para el lenguaje R aquí.\nLa Documentación de GitHub Actions aquí.\ninstall.packages(\u0026#34;usethis\u0026#34;) La primera función muy interesante sobre GitHub Action en el paquete usethis es usethis::browse_github_actions(); con esta función puedes ver las acciones activas que se ejecutan en los más diversos paquetes de R. Este es un muy buen comienzo para darte una idea de cuáles son las Actions que se usan en paquetes grandes de R como \u0026ldquo;shiny\u0026rdquo;, \u0026ldquo;dplyr\u0026rdquo;, etc.\nEl usethis también tiene la función usethis::use_github_action(), que en mi opinión es la forma más fácil de empezar. Creará por ti la estructura de archivos/carpetas necesaria para que GitHub entienda y ejecute tus Actions; en otras palabras, creará la estructura carpeta .github \u0026gt; carpeta workflows \u0026gt; archivo .yaml dentro de la ruta de tu proyecto actual. Esta función también necesita como argumento un nombre de workflow específico (puedes consultar las opciones disponibles aquí); dependiendo de la opción que elijas, puede darte un muy buen punto de partida (a veces no necesitas cambiar nada). Por ejemplo, si ejecutas usethis::use_github_action(\u0026quot;pkgdown\u0026quot;), creará por ti la estructura de carpetas predeterminada (carpeta .github \u0026gt; carpeta workflows \u0026gt; archivo file.yaml) y comenzará un archivo .yaml como este:\non: push: branches: - main - master name: pkgdown jobs: pkgdown: runs-on: macOS-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 - uses: r-lib/actions/setup-r@v1 - uses: r-lib/actions/setup-pandoc@v1 - name: Query dependencies run: | install.packages(\u0026#39;remotes\u0026#39;) saveRDS(remotes::dev_package_deps(dependencies = TRUE), \u0026#34;.github/depends.Rds\u0026#34;, version = 2) writeLines(sprintf(\u0026#34;R-%i.%i\u0026#34;, getRversion()$major, getRversion()$minor), \u0026#34;.github/R-version\u0026#34;) shell: Rscript {0} - name: Restore R package cache uses: actions/cache@v2 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ hashFiles(\u0026#39;.github/R-version\u0026#39;) }}-1-${{ hashFiles(\u0026#39;.github/depends.Rds\u0026#39;) }} restore-keys: ${{ runner.os }}-${{ hashFiles(\u0026#39;.github/R-version\u0026#39;) }}-1- - name: Install dependencies run: | remotes::install_deps(dependencies = TRUE) install.packages(\u0026#34;pkgdown\u0026#34;, type = \u0026#34;binary\u0026#34;) shell: Rscript {0} - name: Install package run: R CMD INSTALL . - name: Deploy package run: | git config --local user.email \u0026#34;actions@github.com\u0026#34; git config --local user.name \u0026#34;GitHub Actions\u0026#34; Rscript -e \u0026#39;pkgdown::deploy_to_branch(new_process = FALSE)\u0026#39; Cubriremos los pasos presentados dentro del archivo .yaml más adelante, así como presentaremos algunos workflows específicos para:\nPublicar tu shiny en shinyapps.io automáticamente\nPublicar tu página de blogdown en GitHub Pages automáticamente.\nRealizar pruebas automáticas en tus paquetes de R.\nProgramar algunas rutinas.\n¡Recuerda que GitHub solo ejecutará los archivos .yaml dentro de la carpeta workflows (que está dentro de la carpeta .github)!\n# Triggered on push branch master on: push: branches: [ master ] El segundo paso es definir el nombre del workflow y el sistema operativo que quieras. GitHub Actions tiene varias opciones de SO para elegir, incluyendo los 3 más populares: ubuntu, macos y windows. Voy a nombrar nuestro procedimiento como \u0026ldquo;Shiny-Deploy\u0026rdquo; y vamos a usar macos-10.15.\nPuedes asociar tus acciones a badges con el paquete usethis. Por ejemplo, si el nombre de tu workflow es \u0026ldquo;Shiny-Deploy\u0026rdquo;, puedes agregar este badge en tu archivo README ejecutando usethis::use_github_actions_badge(\u0026quot;Shiny-Deploy\u0026quot;).\n# Name of the workflow - usethis::use_github_actions_badge(\u0026#34;Shiny-Deploy\u0026#34;) name: Shiny-Deploy # Set the job, the machine and the R version jobs: Shiny-Deploy: runs-on: macos-10.15 strategy: matrix: r-version: [4.0.2] Ahora que ya tenemos nuestra máquina de GitHub Actions, ¡podemos empezar a desarrollar los pasos! Primero clonemos el repositorio desde la rama respectiva que activó la acción.\nPD: de ahora en adelante, todas las acciones estarán \u0026ldquo;dentro\u0026rdquo; de la estructura steps.\nsteps: # Cloning your repository from the respective branch that has triggered it - uses: actions/checkout@v2 ¡Bien! Ya hicimos una copia de nuestros archivos; ahora necesitamos configurar la instalación de R en nuestra máquina de GitHub Actions para poder ejecutar nuestros scripts de R. También configuraremos pandoc para compilar nuestros scripts de shiny o Rmarkdown.\n# set-up an R installation in our GHA machine to run our scripts - name: Set up R ${{ matrix.r-version }} uses: r-lib/actions/setup-R@v1 # for macos with: r-version: ${{ matrix.r-version }} # We will also need pandoc to compile our Shiny or RMarkdown report - name: Setting up pandoc uses: r-lib/actions/setup-pandoc@v1 De ahora en adelante podemos ejecutar algunos scripts de R directamente en la terminal de nuestra máquina de GitHub Actions. Por lo tanto, nuestro próximo paso será instalar todos los paquetes que tu app de shiny necesita. Obviamente, este paso cambiará dependiendo de los paquetes que usaste para construir tu app.\n¡No olvides incluir el paquete rsconnect! Vamos a usar este paquete para conectar nuestra máquina de GitHub al servidor de shinyapps.\n# Install R packages - name: Install dependencies run: | install.packages(c( \u0026#34;rsconnect\u0026#34;, \u0026#34;dplyr\u0026#34;, \u0026#34;shiny\u0026#34;, \u0026#34;shinyjs\u0026#34;, \u0026#34;shinyWidgets\u0026#34;, \u0026#34;shinyalert\u0026#34;, \u0026#34;shinycssloaders\u0026#34;, \u0026#34;evaluate\u0026#34;, \u0026#34;highr\u0026#34;, \u0026#34;knitr\u0026#34;, \u0026#34;markdown\u0026#34;, \u0026#34;rmarkdown\u0026#34;, \u0026#34;stringi\u0026#34;, \u0026#34;stringr\u0026#34;, \u0026#34;tinytex\u0026#34;, \u0026#34;xfun\u0026#34; )) shell: Rscript {0} Ahora viene la parte complicada. Para hacer la conexión entre tu máquina de GitHub Actions y tu cuenta de shiny apps, necesitamos configurar tu token y key de shiny apps. Evidentemente, por razones de seguridad no quieres publicar tus credenciales de shinyapps para que cualquiera que acceda a tu repositorio de GitHub las vea. Sin embargo, también necesitamos tu token y key para poder publicar tu app automáticamente; por eso vamos a usar la función GitHub Secrets!\nPrimero necesitas ir a tu cuenta de shiny apps, hacer clic en tu nombre de perfil y entrar en la opción de tokens.\nSi aún no has creado tus tokens de shinyapps, o si quieres usar uno nuevo, puedes hacer clic en el botón + Add Token. Una vez que lo hagas, aparecerá una nueva línea y deberías poder ver tu Token pero no tu Secret. Necesitas presionar el botón Show seguido del Show Secret para poder copiar tu credencial Secret.\nAhora necesitamos incluir estas credenciales en GitHub Secrets. Para ello debes entrar en la página de tu repositorio de GitHub e ir a Settings.\nEn el menú de la izquierda deberías poder ver la opción Secrets. Una vez que entres en la pestaña Secrets verás el título \u0026ldquo;Actions secrets\u0026rdquo;, y justo a su lado verás el botón \u0026ldquo;New repository secret\u0026rdquo;. Necesitas hacer clic en este botón para crear tus variables de entorno encriptadas (en este caso, tus credenciales de shinyapps).\nVamos a crear 2 variables de entorno diferentes: la primera llamada \u0026ldquo;SHINYAPP_TOKEN\u0026rdquo; y la segunda llamada \u0026ldquo;SHINYAPP_SECRET\u0026rdquo; (por supuesto, puedes ponerles el nombre que quieras). Una vez que hagas clic en el botón \u0026ldquo;New repository secret\u0026rdquo;, deberás proporcionar el nombre de tu variable y su valor, y presionar \u0026ldquo;Add Secret\u0026rdquo;, como puedes ver a continuación.\n¡Tu Secret y Token no necesitan estar entre comillas (\u0026ldquo;my token\u0026rdquo;)!\nBien, ahora podemos usar estas dos variables dentro de nuestro archivo .yaml y deberíamos poder publicar nuestra app en el servidor de shinyapps. También debes proporcionar tu nombre de cuenta de shinyapps, el nombre de tu app y el directorio de los scripts de tu app. Claro, si quieres puedes configurar todo esto usando GitHub Secrets.\n# Connect on shinyapps server - name: Connect to ShinyApps env: # set the shinyapps keys as environment variables SHINY_TOKEN: ${{ secrets.SHINYAPP_TOKEN }} SHINY_SECRET: ${{ secrets.SHINYAPP_SECRET }} run: | shiny_token = Sys.getenv(\u0026#34;SHINY_TOKEN\u0026#34;) shiny_secret = Sys.getenv(\u0026#34;SHINY_SECRET\u0026#34;) rsconnect::setAccountInfo(name = \u0026#39;adsoncostanzi\u0026#39;, token = shiny_token, secret = shiny_secret) shell: Rscript {0} # deploy the app on shinyapps server - name: Deploy to shinyapps.io run: | rsconnect::deployApp(appName = \u0026#34;soothsayeR\u0026#34;, appDir = \u0026#34;app\u0026#34;) shell: Rscript {0} ¡Eso es todo! Ahora GitHub publicará tu shiny en shinyapps cada vez que hagas \u0026ldquo;push\u0026rdquo; en la rama master.\nPor razones de copiar y pegar, aquí está el archivo .yaml completo.\n¡Sigue la indentación, es una parte esencial del código!\n# Triggered on push branch master on: push: branches: [ master ] # Name of the workflow - usethis::use_github_actions_badge(\u0026#34;Shiny-Deploy\u0026#34;) name: Shiny-Deploy # Set the job, the machine and the R version jobs: Shiny-Deploy: #runs-on: ubuntu-latest runs-on: macos-10.15 strategy: matrix: r-version: [4.0.2] steps: # Cloning your repository from the respective branch that has triggered it - uses: actions/checkout@v2 # set-up an R installation in our GHA machine to run our scripts - name: Set up R ${{ matrix.r-version }} uses: r-lib/actions/setup-R@v1 # for macos with: r-version: ${{ matrix.r-version }} # We will also need pandoc to compile our Shiny or RMarkdown report - name: Setting up pandoc uses: r-lib/actions/setup-pandoc@v1 # Install R packages - name: Install dependencies run: | install.packages(c( \u0026#34;rsconnect\u0026#34;, \u0026#34;dplyr\u0026#34;, \u0026#34;shiny\u0026#34;, \u0026#34;shinyjs\u0026#34;, \u0026#34;shinyWidgets\u0026#34;, \u0026#34;shinyalert\u0026#34;, \u0026#34;shinycssloaders\u0026#34;, \u0026#34;evaluate\u0026#34;, \u0026#34;highr\u0026#34;, \u0026#34;knitr\u0026#34;, \u0026#34;markdown\u0026#34;, \u0026#34;rmarkdown\u0026#34;, \u0026#34;stringi\u0026#34;, \u0026#34;stringr\u0026#34;, \u0026#34;tinytex\u0026#34;, \u0026#34;xfun\u0026#34; )) shell: Rscript {0} # Connect in shinyapps server - name: Connect to ShinyApps env: # set the shinyapps keys as environment variables SHINY_TOKEN: ${{ secrets.SHINYAPP_TOKEN }} SHINY_SECRET: ${{ secrets.SHINYAPP_SECRET }} run: | shiny_token = Sys.getenv(\u0026#34;SHINY_TOKEN\u0026#34;) shiny_secret = Sys.getenv(\u0026#34;SHINY_SECRET\u0026#34;) rsconnect::setAccountInfo(name = \u0026#39;adsoncostanzi\u0026#39;, token = shiny_token, secret = shiny_secret) shell: Rscript {0} # deploy the app on shinyapps server - name: Deploy to shinyapps.io run: | rsconnect::deployApp(appName = \u0026#34;soothsayeR\u0026#34;, appDir = \u0026#34;app\u0026#34;) shell: Rscript {0} Publicación automática de Blogdown ¿Qué tal hacer que tu blogdown se publique automáticamente en GitHub Pages? Cada vez que escribas un nuevo post solo necesitarás hacer \u0026ldquo;push\u0026rdquo; y GitHub Actions se encargará del resto. Este procedimiento funciona de manera muy similar al de shiny, ¡así que empecemos nuestro archivo .yaml!\nPara la publicación de blogdown vamos a usar dos ramas diferentes: la primera llamada \u0026ldquo;source\u0026rdquo;, que contendrá el lado de desarrollo de nuestro blogdown, y la rama \u0026ldquo;master\u0026rdquo;, que expondrá la página compilada (la rama master recibirá el resultado de blogdown::build_site(local = FALSE)).\n¡La rama master DEBE ser la que tenga el contenido de build_site()!\nDe esta manera configuraremos nuestro trigger como un \u0026ldquo;push\u0026rdquo; en la rama \u0026ldquo;source\u0026rdquo;:\n# Triggered on push branch source on: push: branches: - source En el siguiente paso definiremos el nombre del workflow y el SO que queremos usar. Para este ejemplo, vamos a nombrar nuestro workflow como \u0026ldquo;deployblog\u0026rdquo; y el SO será Ubuntu 18.04.\n# Name of the workflow - usethis::use_github_actions_badge(\u0026#34;deployblog\u0026#34;) name: deployblog # Set the job, the machine jobs: deployblog: name: Render and deploy blogdown runs-on: ubuntu-18.04 La parte más fácil está hecha; ¡ahora empecemos con los pasos! Vamos a clonar el repositorio (en la rama \u0026ldquo;source\u0026rdquo;) y configurar R y pandoc, como hicimos en la sección de publicación de shiny.\nPD: de ahora en adelante, todas las acciones estarán \u0026ldquo;dentro\u0026rdquo; de la estructura steps.\nsteps: # Cloning your repository from the respective branch that has triggered it - uses: actions/checkout@v2 with: submodules: true fetch-depth: 0 # set-up an R installation in our GHA machine to run our scripts - uses: r-lib/actions/setup-r@v1 # We will also need pandoc to compile our Shiny or RMarkdown report - uses: r-lib/actions/setup-pandoc@v1 Ahora que tenemos nuestros scripts y R configurados, podemos continuar con la instalación de los paquetes, así como instalar HUGO, de la siguiente manera:\n# Install R packages - name: Install r packages run: | Rscript -e \u0026#39;install.packages(c(\u0026#34;remotes\u0026#34;, \u0026#34;rmarkdown\u0026#34;))\u0026#39; \\ -e \u0026#39;remotes::install_github(\u0026#34;rstudio/blogdown\u0026#34;)\u0026#39; - name: install hugo # Install Hugo run: Rscript -e \u0026#39;blogdown::install_hugo(extended = TRUE, version = \u0026#34;0.78.2\u0026#34;)\u0026#39; - name: Get themes run: git submodule update --remote Terminado eso, deberíamos poder renderizar/compilar nuestro blogdown en una carpeta específica (en este caso será la carpeta \u0026ldquo;public\u0026rdquo;) usando la función blogdown::build_site(local = FALSE). Hecho eso, solo necesitamos subir el contenido de la carpeta \u0026ldquo;public\u0026rdquo; a la rama master y ¡tu blogdown estará en línea en GitHub Pages!\n- name: Look at files run: ls ./public - name: Render blog run: Rscript -e \u0026#39;blogdown::build_site(local = FALSE)\u0026#39; - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: master ¡ROBÉ ESTE SCRIPT DE MI BUEN AMIGO LUCAS GODOY (¡él también me enseñó cómo hacerlo funcionar)!\nPor razones de copiar y pegar, aquí está el archivo .yaml completo.\n# Triggered on push branch source on: push: branches: - source # Name of the workflow - usethis::use_github_actions_badge(\u0026#34;deployblog\u0026#34;) name: deployblog # Set the job, the machine jobs: deployblog: name: Render and deploy blogdown runs-on: ubuntu-18.04 steps: # Cloning your repository from the respective branch that has triggered it - uses: actions/checkout@v2 with: submodules: true fetch-depth: 0 # set-up an R installation in our GHA machine to run our scripts - uses: r-lib/actions/setup-r@v1 # We will also need pandoc to compile our Shiny or RMarkdown report - uses: r-lib/actions/setup-pandoc@v1 # Install R packages - name: Install r packages run: | Rscript -e \u0026#39;install.packages(c(\u0026#34;remotes\u0026#34;, \u0026#34;rmarkdown\u0026#34;))\u0026#39; \\ -e \u0026#39;remotes::install_github(\u0026#34;rstudio/blogdown\u0026#34;)\u0026#39; - name: install hugo # Install Hugo run: Rscript -e \u0026#39;blogdown::install_hugo(extended = TRUE, version = \u0026#34;0.78.2\u0026#34;)\u0026#39; - name: Get themes run: git submodule update --remote - name: Look at files run: ls ./public - name: Render blog run: Rscript -e \u0026#39;blogdown::build_site(local = FALSE)\u0026#39; - name: Deploy uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_branch: master publish_dir: ./public Pruebas automáticas Diría que ejecutar pruebas manualmente puede ser el trabajo que más tiempo consume de todos los presentados en este post, y es por eso que realizar pruebas automáticas puede ahorrarte muchas horas de trabajo. Sé que las pruebas automáticas son muy específicas; en otras palabras, dependerá del tipo de pruebas que quieras realizar. Sin embargo, podemos tener un muy buen punto de partida con el paquete usethis.\nPor ejemplo, al ejecutar la función usethis::use_github_action_check_full() se creará el procedimiento R-CMD-check predeterminado para ti en una estructura de GitHub Actions. El R-CMD-check estimulará el uso de tus códigos en los más diversos entornos, como windows, ubuntu y macos, los tres ejecutando también diferentes versiones de R. Mi consejo es usar como punto de partida el .yaml proporcionado por la función usethis::use_github_action_check_full() para realizar tus propias pruebas automáticas.\nPuedes encontrar a continuación el archivo .yaml generado por la función usethis::use_github_action_check_full():\non: push: branches: - main - master pull_request: branches: - main - master name: R-CMD-check jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} name: ${{ matrix.config.os }} (${{ matrix.config.r }}) strategy: fail-fast: false matrix: config: - {os: macOS-latest, r: \u0026#39;release\u0026#39;} - {os: windows-latest, r: \u0026#39;release\u0026#39;} - {os: windows-latest, r: \u0026#39;3.6\u0026#39;} - {os: ubuntu-18.04, r: \u0026#39;devel\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;, http-user-agent: \u0026#34;R/4.0.0 (ubuntu-18.04) R (4.0.0 x86_64-pc-linux-gnu x86_64 linux-gnu) on GitHub Actions\u0026#34; } - {os: ubuntu-18.04, r: \u0026#39;release\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;} - {os: ubuntu-18.04, r: \u0026#39;oldrel\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;} - {os: ubuntu-18.04, r: \u0026#39;3.5\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;} - {os: ubuntu-18.04, r: \u0026#39;3.4\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;} - {os: ubuntu-18.04, r: \u0026#39;3.3\u0026#39;, rspm: \u0026#34;https://packagemanager.rstudio.com/cran/__linux__/bionic/latest\u0026#34;} env: RSPM: ${{ matrix.config.rspm }} GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 - uses: r-lib/actions/setup-r@v1 id: install-r with: r-version: ${{ matrix.config.r }} http-user-agent: ${{ matrix.config.http-user-agent }} - uses: r-lib/actions/setup-pandoc@v1 - name: Install pak and query dependencies run: | install.packages(\u0026#34;pak\u0026#34;, repos = \u0026#34;https://r-lib.github.io/p/pak/dev/\u0026#34;) saveRDS(pak::pkg_deps(\u0026#34;local::.\u0026#34;, dependencies = TRUE), \u0026#34;.github/r-depends.rds\u0026#34;) shell: Rscript {0} - name: Restore R package cache uses: actions/cache@v2 with: path: | ${{ env.R_LIBS_USER }} !${{ env.R_LIBS_USER }}/pak key: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles(\u0026#39;.github/r-depends.rds\u0026#39;) }} restore-keys: ${{ matrix.config.os }}-${{ steps.install-r.outputs.installed-r-version }}-1- - name: Install system dependencies if: runner.os == \u0026#39;Linux\u0026#39; run: | pak::local_system_requirements(execute = TRUE) pak::pkg_system_requirements(\u0026#34;rcmdcheck\u0026#34;, execute = TRUE) shell: Rscript {0} - name: Install dependencies run: | pak::local_install_dev_deps(upgrade = TRUE) pak::pkg_install(\u0026#34;rcmdcheck\u0026#34;) shell: Rscript {0} - name: Session info run: | options(width = 100) pkgs \u0026lt;- installed.packages()[, \u0026#34;Package\u0026#34;] sessioninfo::session_info(pkgs, include_base = TRUE) shell: Rscript {0} - name: Check env: _R_CHECK_CRAN_INCOMING_: false run: | options(crayon.enabled = TRUE) rcmdcheck::rcmdcheck(args = c(\u0026#34;--no-manual\u0026#34;, \u0026#34;--as-cran\u0026#34;), error_on = \u0026#34;warning\u0026#34;, check_dir = \u0026#34;check\u0026#34;) shell: Rscript {0} - name: Show testthat output if: always() run: find check -name \u0026#39;testthat.Rout*\u0026#39; -exec cat \u0026#39;{}\u0026#39; \\; || true shell: bash - name: Upload check results if: failure() uses: actions/upload-artifact@main with: name: ${{ matrix.config.os }}-r${{ matrix.config.r }}-results path: check Rutinas programadas GitHub Actions también ofrece la opción de programar rutinas; en otras palabras, puedes definir como triggers cualquier momento específico que quieras. Para ello, GitHub Actions usa la sintaxis cron, que es la parte difícil (al menos para mí, que nunca la había usado). Primero, ¡entendamos la sintaxis que GitHub Actions usa para ejecutar las rutinas programadas!\nLa sintaxis cron está dividida en 5 partes (*****):\nLa primera parte sirve para definir el minuto (0 - 59)\nLa segunda parte sirve para definir la hora (0 - 23)\nLa tercera parte sirve para definir el día del mes (1 - 31)\nLa cuarta parte sirve para definir el mes (1 - 12)\nLa quinta parte sirve para definir el día de la semana (0 - 6)\nObviamente, ¡no quieres ejecutar tu rutina solo una vez! Entonces, necesitas alguna forma de abstraer algunas de las partes; en la sintaxis cron, eso se hace usando un asterisco (*). Por ejemplo, ***** significa ejecutar la rutina cada minuto, todos los días.\nTen en cuenta que las horas de GitHub se basan en UTC!\nAquí hay algunos ejemplos útiles que tomé de este post:\n# Every Monday at 1PM UTC (9AM EST) 0 13 * * 1 # At the end of every day 0 0 * * * # Every 10 minutes */10 * * * * ¿Y la sintaxis .yaml? Es muy simple: en lugar de usar \u0026ldquo;on\u0026rdquo; seguido de \u0026ldquo;push\u0026rdquo;, \u0026ldquo;merge\u0026rdquo;, \u0026ldquo;pull_request\u0026rdquo;, etc., debes escribir \u0026ldquo;schedule\u0026rdquo; y ¡listo!\non: schedule: - cron: \u0026#39;0 0 * * *\u0026#39; Eso es todo Espero que alguien encuentre útil este tutorial. Como siempre, tus comentarios son muy apreciados; ¡no dudes en ponerte en contacto conmigo a través de las redes sociales! 😄\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/github-actions-for-r-users/","summary":"\u003ch2 id=\"motivación\"\u003eMotivación\u003c/h2\u003e\n\u003cp\u003eRecientemente algunos amigos me presentaron \u003cstrong\u003eGitHub Actions\u003c/strong\u003e y cómo podría ayudarme a ejecutar tareas como: publicar mis \u003cem\u003eShiny Apps\u003c/em\u003e, publicar este \u003cem\u003eBlogdown\u003c/em\u003e, realizar pruebas automáticas en paquetes, actualizar datos y más. Así que decidí probarlo, y fue tan simple y me ahorró tantas horas de trabajo que decidí escribir este post explicando cómo los desarrolladores de R pueden hacer buen uso de esta increíble herramienta.\u003c/p\u003e\n\u003cp\u003ePrimero, las referencias que usé para empezar con \u003cem\u003eGitHub Actions\u003c/em\u003e:\u003c/p\u003e","title":"GitHub Actions para Usuarios de R"},{"content":" Resumen GitHub: adsoncostanzifilho/CSGo\nEl paquete CSGo es un cliente de R para acceder a la API REST de Steam, específicamente para los datos del juego Counter-Strike Global Offensive (CS Go). Consulta el sitio web de documentación de Steam y la Página del Paquete para más información.\nInstalación Para obtener la versión actual publicada desde CRAN:\ninstall.packages(\u0026#34;CSGo\u0026#34;) Para obtener la versión de desarrollo actual desde GitHub:\n# install.packages(\u0026#34;devtools\u0026#34;) devtools::install_github(\u0026#34;adsoncostanzifilho/CSGo\u0026#34;) Ejemplo El primer paso para usar el paquete CSGo es tener tus propias credenciales (API key) para obtener los datos de CSGo desde la API de Steam. Para más información sobre cómo obtener tu propia API Key, ejecuta en tu R vignette(\u0026quot;auth\u0026quot;, package = \u0026quot;CSGo\u0026quot;), o haz clic aquí.\nAhora que ya tienes tu API Key, deberías poder recolectar tus propios datos de CSGo, así como los datos de tus amigos. ¡Espero que a mi amigo Rodrigo no le importe que juguemos con sus datos (él es el \u0026lsquo;76561198263364899\u0026rsquo;)!\nPrimero recolectemos sus estadísticas de CSGo:\nlibrary(CSGo) # to get the statistics of the user 76561198263364899 rodrigo_stats \u0026lt;- get_stats_user(api_key = \u0026#39;your_key\u0026#39;, user_id = \u0026#39;76561198263364899\u0026#39;) Filtremos el data frame obtenido por \u0026ldquo;kills\u0026rdquo; y \u0026ldquo;weapon\u0026rdquo; para crear un análisis de muertes por tipo de arma.\nlibrary(dplyr) library(stringr) rodrigo_weapon_kill \u0026lt;- rodrigo_stats %\u0026gt;% filter( str_detect(name, \u0026#39;kill\u0026#39;), type == \u0026#39; weapon info\u0026#39; ) %\u0026gt;% arrange(desc(value)) ¡Ahora echemos un vistazo al gráfico!\nPD: Para hacer el gráfico aún más bonito, recomiendo obtener la fuente \u0026ldquo;Quantico\u0026rdquo; de Google fonts usando el paquete showtext!\nlibrary(ggplot2) library(showtext) ## Loading Google fonts (https://fonts.google.com/) font_add_google(\u0026#34;Quantico\u0026#34;, \u0026#34;quantico\u0026#34;) rodrigo_weapon_kill %\u0026gt;% top_n(n = 10, wt = value) %\u0026gt;% ggplot(aes(x = name_match, y = value, fill = name_match)) + geom_col() + ggtitle(\u0026#34;KILLS BY WEAPON\u0026#34;) + ylab(\u0026#34;Number of Kills\u0026#34;) + xlab(\u0026#34;\u0026#34;) + labs(fill = \u0026#34;Weapon Name\u0026#34;) + theme_csgo(text = element_text(family = \u0026#34;quantico\u0026#34;)) + scale_fill_csgo() Entonces, estas son las 10 mejores armas por muertes, pero\u0026hellip; ¿Qué pasa con la eficiencia? ¿Es la ak47 el arma más eficiente de Rodrigo? Primero, definamos \u0026ldquo;eficiencia\u0026rdquo;:\nkills_efficiency significa cuántos disparos hizo para matar (ej.: el 32% de los disparos matarán)\nhits_efficiency significa cuántos disparos para dar en el blanco; esto está más relacionado con la habilidad de Rodrigo con cada arma (ej.: el 35% de los disparos darán en el blanco).\nhits_to_kill significa cuántos impactos son necesarios para matar; esto está más relacionado con el poder/eficiencia del arma (ej.: el 91% de los impactos matarán).\nrodrigo_efficiency \u0026lt;- rodrigo_stats %\u0026gt;% filter( name_match %in% c(\u0026#34;ak47\u0026#34;, \u0026#34;aug\u0026#34;, \u0026#34;awp\u0026#34;, \u0026#34;fiveseven\u0026#34;, \u0026#34;hkp2000\u0026#34;, \u0026#34;m4a1\u0026#34;, \u0026#34;mp7\u0026#34;, \u0026#34;p90\u0026#34;, \u0026#34;sg556\u0026#34;, \u0026#34;xm1014\u0026#34;) ) %\u0026gt;% mutate( stat_type = case_when( str_detect(name, \u0026#34;shots\u0026#34;) ~ \u0026#34;shots\u0026#34;, str_detect(name, \u0026#34;hits\u0026#34;) ~ \u0026#34;hits\u0026#34;, str_detect(name, \u0026#34;kills\u0026#34;) ~ \u0026#34;kills\u0026#34; ) ) %\u0026gt;% pivot_wider( names_from = stat_type, id_cols = name_match, values_from = value ) %\u0026gt;% mutate( kills_efficiency = kills/shots*100, hits_efficiency = hits/shots*100, hits_to_kill = kills/hits*100 ) kbl(rodrigo_efficiency) %\u0026gt;% kable_styling() name_match kills shots hits kills_efficiency hits_efficiency hits_to_kill fiveseven 1288 28187 5558 4.569482 19.71831 23.17380 xm1014 5611 205982 42541 2.724024 20.65278 13.18963 p90 3469 133273 20245 2.602928 15.19062 17.13510 awp 2051 6260 2235 32.763578 35.70288 91.76734 ak47 6969 154852 24823 4.500426 16.03014 28.07477 aug 2120 37949 8487 5.586445 22.36423 24.97938 hkp2000 1401 36975 6737 3.789047 18.22042 20.79561 sg556 1243 25091 4567 4.953968 18.20175 27.21699 mp7 1788 52657 10186 3.395560 19.34406 17.55350 m4a1 3526 81126 14687 4.346325 18.10394 24.00763 rodrigo_efficiency %\u0026gt;% top_n(n = 10, wt = kills) %\u0026gt;% ggplot(aes(x = name_match, size = shots)) + geom_point(aes(y = kills_efficiency, color = \u0026#34;Kills Efficiency\u0026#34;)) + geom_point(aes(y = hits_efficiency, color = \u0026#34;Hits Efficiency\u0026#34;)) + geom_point(aes(y = hits_to_kill, color = \u0026#34;Hits to Kill\u0026#34;)) + ggtitle(\u0026#34;WEAPON EFFICIENCY\u0026#34;) + ylab(\u0026#34;Efficiency (%)\u0026#34;) + xlab(\u0026#34;\u0026#34;) + labs(color = \u0026#34;Efficiency Type\u0026#34;, size = \u0026#34;Shots\u0026#34;) + theme_csgo( text = element_text(family = \u0026#34;quantico\u0026#34;), panel.grid.major.x = element_line(size = .1, color = \u0026#34;black\u0026#34;,linetype = 2) ) + scale_color_csgo() En conclusión, le aconsejaría a Rodrigo usar la **awp** en sus próximas partidas, porque esta arma presentó la mejor eficiencia en términos de **disparos para matar**, **disparos para dar en el blanco** e **impactos para matar**. Pero definitivamente necesitamos más disparos con esta arma para ver si esta eficiencia se mantiene.. jajajaja ","permalink":"https://adsoncostanzifilho.github.io/es/blog/csgo-package/","summary":"\u003cscript src=\"https://adsoncostanzifilho.github.io/es/blog/csgo-package/index_files/kePrint/kePrint.js\"\u003e\u003c/script\u003e\n\u003clink href=\"https://adsoncostanzifilho.github.io/es/blog/csgo-package/index_files/lightable/lightable.css\" rel=\"stylesheet\" /\u003e\n\u003ch2 id=\"resumen\"\u003eResumen\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eGitHub:\u003c/strong\u003e \u003ca href=\"https://github.com/adsoncostanzifilho/CSGo\"\u003eadsoncostanzifilho/CSGo\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eEl paquete \u003cstrong\u003eCSGo\u003c/strong\u003e es un cliente de R para acceder a la API REST de Steam, específicamente para los datos del juego Counter-Strike Global Offensive (CS Go). Consulta el \u003ca href=\"https://developer.valvesoftware.com/wiki/Steam_Web_API\"\u003esitio web de documentación de Steam\u003c/a\u003e y la \u003ca href=\"https://adsoncostanzifilho.github.io/CSGo/\"\u003ePágina del Paquete\u003c/a\u003e para más información.\u003c/p\u003e\n\u003ch2 id=\"instalación\"\u003eInstalación\u003c/h2\u003e\n\u003cp\u003ePara obtener la versión actual publicada desde \u003ca href=\"https://cran.r-project.org/web/packages/CSGo/index.html\"\u003eCRAN\u003c/a\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003einstall.packages\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;CSGo\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003ePara obtener la versión de desarrollo actual desde \u003ca href=\"https://github.com/adsoncostanzifilho/CSGo\"\u003eGitHub\u003c/a\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-r\" data-lang=\"r\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# install.packages(\u0026#34;devtools\u0026#34;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edevtools\u003c/span\u003e\u003cspan class=\"o\"\u003e::\u003c/span\u003e\u003cspan class=\"nf\"\u003einstall_github\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;adsoncostanzifilho/CSGo\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"ejemplo\"\u003eEjemplo\u003c/h2\u003e\n\u003cp\u003eEl primer paso para usar el paquete \u003ccode\u003eCSGo\u003c/code\u003e es tener tus propias credenciales (API key) para obtener los datos de CSGo desde la API de Steam. Para más información sobre cómo obtener tu propia API Key, ejecuta en tu R \u003ccode\u003evignette(\u0026quot;auth\u0026quot;, package = \u0026quot;CSGo\u0026quot;)\u003c/code\u003e, o haz clic \u003ca href=\"https://cran.r-project.org/web/packages/CSGo/vignettes/auth.html\"\u003eaquí\u003c/a\u003e.\u003c/p\u003e","title":"Paquete CSGo"},{"content":"Motivación Si estás usando un script más de 3 veces, es hora de crear una función, y si estás usando una función en 3 proyectos diferentes, es hora de crear un paquete. \u0026ldquo;Lo escuché de alguien, pero no recuerdo de quién..\u0026rdquo;\nRecientemente experimenté todo el flujo para crear un nuevo paquete de R con la ayuda de paquetes increíbles como devtools, usethis, pkgdown y roxygen2. Por eso decidí escribir sobre ello mientras todavía recuerdo todos los pasos necesarios para hacer que tus funciones locales estén disponibles para la comunidad de R (CRAN y Github).\nEl material que seguí para guiarme en este proceso fue el R Packages Book de Hadley Wickham. Por supuesto, hay MUCHO MÁS contenido en su libro que el presentado aquí, pero tal vez este post también pueda ayudar a alguien de alguna manera.\nFunciones Un paquete no es más que un montón de funciones juntas en el mismo lugar (compartiendo el mismo alcance), así que la clave principal para tener un buen paquete es también tener buenas funciones.\nEste post no cubrirá las pautas para crear funciones útiles. Para eso te recomiendo echar un vistazo a la sección Functions del Advanced R Book.\nPara facilitarte los próximos pasos a la hora de empaquetar tus funciones, es importante tener en cuenta dos cosas:\nPrimero, desarrolla tus funciones lo más genéricas posible y siempre incluye comentarios explicando las entradas, salidas y al menos un ejemplo de cómo usarla.\nSegundo, recuerda todos los paquetes que usaste y, si es posible, usa siempre la estructura package::function cuando uses funciones externas dentro de la tuya.\nPD: Ten cuidado con esos paquetes que siempre usamos pero que solemos olvidar porque \u0026ldquo;siempre estuvieron ahí\u0026rdquo;, como stats y utils.\n¡El R base es el único que no necesita ser mencionado!\nAhora que tenemos nuestras funciones en buena forma, pasemos al desarrollo del paquete en sí.\nCómo empezar Lo primero que hay que hacer es instalar los paquetes que nos harán la vida más fácil.\ninstall.packages(c(\u0026#34;devtools\u0026#34;, \u0026#34;usethis\u0026#34;, \u0026#34;pkgdown\u0026#34;, \u0026#34;roxygen2\u0026#34;)) Si también quieres compartir tu paquete en Github, ahora es un buen momento para crear un nuevo repositorio de Github con el nombre que quieras darle a tu paquete, por ejemplo \u0026lsquo;mypackage\u0026rsquo;. Clona este repositorio vacío dentro de alguna carpeta que quieras.\nAhora debería ser posible ejecutar el comando devtools::create(\u0026quot;~/path/mypackage\u0026quot;) (dándole la ruta del repositorio de Github que acabas de clonar). Esta línea de código creará la estructura de carpetas y archivos que seguiremos de ahora en adelante. En cuanto lo ejecutes, se abrirá una nueva sesión de RStudio con estructura de proyecto R y te ubicará dentro de la carpeta \u0026ldquo;~/path/mypackage\u0026rdquo;. Si todo salió bien, deberías poder ver una carpeta llamada \u0026ldquo;R\u0026rdquo; y los archivos \u0026ldquo;DESCRIPTION\u0026rdquo; y \u0026ldquo;NAMESPACE\u0026rdquo;.\nCarpeta R: La carpeta R será el lugar donde debes poner tus scripts (los que contienen tus funciones, los archivos .R). No hay una regla sobre cómo debes organizar tus scripts dentro de esta carpeta; sin embargo, a mí me gusta seguir la regla de una función por script. Para mí, tener una función por script hace que el proceso de debugging y documentación sea más fácil. Pero al final, ¡depende de ti!\nDESCRIPTION: Este archivo expondrá información importante sobre tu paquete. No es tan difícil completar las opciones principales de este archivo; de hecho, el archivo tiene muy buenas explicaciones sobre cómo completarlo correctamente. También tenemos funciones como usethis::use_package(\u0026quot;packagename\u0026quot;) para ayudarnos a completar las otras secciones de este archivo. Hablaremos más sobre esto más adelante.\nNAMESPACE: Este archivo contiene todas las funciones que el usuario de tu paquete podrá usar (todas esas funciones definidas con un @export; también cubriremos más sobre esto más adelante). No debes editar este archivo; en su lugar, puedes ejecutar devtools::document() para actualizarlo.\n#\u0026#39; Title #\u0026#39; #\u0026#39; @param a #\u0026#39; @param b #\u0026#39; #\u0026#39; @return #\u0026#39; @export #\u0026#39; #\u0026#39; @examples myfunction \u0026lt;- function(a,b) { return(a+b) } Ahora solo es cuestión de completar las opciones presentadas con explicaciones claras sobre el uso de la función y los parámetros. Además, debes proporcionar al menos un ejemplo de cómo usarla y explicar qué debe esperar el usuario a cambio.\nA veces el ejemplo que proporcionamos solo funcionará en condiciones muy específicas. Para esos casos debes crear tus ejemplos dentro de \\dontrun{}; esto evitará que se ejecute mientras compilas y verificas tu paquete.\nTen en cuenta que el esqueleto predeterminado que nos proporciona roxygen2 considera el #' @export. Eso solo significa que esta función quedará expuesta al usuario final; en otras palabras, el usuario debería poder ejecutar mypackage::myfunction(). Si por alguna razón no quieres exportar esta función, solo puedes eliminar esta línea de tu script.\nLas funciones definidas sin el #' @export funcionarán internamente sin problemas, pero el usuario final solo podrá acceder a ellas con la estructura :::, como mypackage:::myfunction().\nAl final de este proceso, tu script de función debería ser algo como esto:\n#\u0026#39; My Function #\u0026#39; #\u0026#39; This function provides the sum of two values (the worst example ever, I know!). #\u0026#39; #\u0026#39; @param a the first numeric value #\u0026#39; @param b the second numeric value #\u0026#39; #\u0026#39; @return a numeric value with the sum of a + b #\u0026#39; @export #\u0026#39; #\u0026#39; @examples #\u0026#39; \\dontrun{ #\u0026#39; ## the parameters must be numeric #\u0026#39; #\u0026#39; myfunction(a = 1, b = 1) #\u0026#39; } myfunction \u0026lt;- function(a,b) { return(a+b) } Una vez que tengas tu función documentada, debes ejecutar devtools::document(); esto creará/actualizará la carpeta llamada \u0026ldquo;man\u0026rdquo;. Esta carpeta almacenará toda la documentación de tus funciones. ¡No olvides ejecutar devtools::document() cada vez que actualices las descripciones de tus funciones!\nTambién puedes ejecutar devtools::load_all() para cargar tu paquete en tu sesión actual de R; luego deberías poder ver cómo se ve tu documentación ejecutando help('mypackage::myfunction') o ?mypackage::myfunction.\nPaquetes externos Es muy poco probable que crees tus funciones sin usar NINGUNA dependencia (paquetes externos), y eso no es un problema en absoluto. Sin embargo, debes proporcionar esta información al usuario final de alguna manera; de lo contrario, los usuarios no podrán ejecutar tus códigos como se espera.\nEl lugar correcto para esta información es dentro del archivo DESCRIPTION, en la sección \u0026ldquo;Imports\u0026rdquo;. Es posible completarla a mano abriendo el archivo DESCRIPTION e incluyendo todos los paquetes que usaste en tus funciones (separados por \u0026ldquo;,\u0026rdquo;) O puedes usar la función usethis::use_package(\u0026quot;ggplot2\u0026quot;) y ella se encargará de completarla por ti.\nLa función use_package también ofrece opciones como la versión mínima del paquete y el tipo de dependencia.\nNO USES library() O require() EN TUS SCRIPTS DE R!!!\nOtra posibilidad es incluir solo una función de un paquete externo. Esto es muy común porque a veces usamos solo una función de un paquete específico y no queremos \u0026ldquo;importar\u0026rdquo; todo el paquete, sino solo esa función que estamos usando. Para eso puedes incluir @importFrom package_name function_name en la documentación de tu función; de esta manera podrás usar la función sin declarar el paquete del que proviene. De ahora en adelante estará disponible como tus propias funciones: mypackage::function_name().\nDigamos que queremos incluir la función beep() del paquete beepr, pero no queremos todo beepr. El script debería ser algo así:\n#\u0026#39; My Function #\u0026#39; #\u0026#39; This function provides the sum of two values (the worst example ever, I know!). #\u0026#39; #\u0026#39; @param a the first numeric value #\u0026#39; @param b the second numeric value #\u0026#39; #\u0026#39; @return a numeric value with the sum of a + b #\u0026#39; @export #\u0026#39; #\u0026#39; @importFrom beepr beep #\u0026#39; #\u0026#39; @examples #\u0026#39; \\dontrun{ #\u0026#39; ## the parameters must be numeric #\u0026#39; #\u0026#39; myfunction(a = 1, b = 1) #\u0026#39; } myfunction \u0026lt;- function(a,b) { beep() return(a+b) } De ahora en adelante, la función beep() debería ser parte de mypackage. Si ejecutas devtools::document() y devtools::load_all(), verás que mypackage::beep() va a funcionar.\nTambién es muy común usar el operador %\u0026gt;% dentro de tus funciones. Como sabemos, el operador pipe proviene del paquete magrittr, pero no es necesario importar todo el paquete magrittr solo para usar el %\u0026gt;%. Para esto puedes ejecutar usethis::use_pipe() y ¡eso es todo!\nIncluir datos ¿Qué pasa si mi paquete usa datos externos? Esa es otra posibilidad muy común y es muy fácil incluir fuentes de datos externas en tu paquete. ¡Gracias de nuevo al paquete usethis por proporcionarnos la función use_data()! Entonces, para hacer que tus datos externos estén disponibles dentro del entorno de tus funciones, solo necesitas ejecutar usethis::use_data(mydf), así:\nmydf \u0026lt;- data.frame( x = rnorm(10,0,1), y = runif(10) ) usethis::use_data(mydf) De ahora en adelante deberías poder usar el data frame \u0026ldquo;mydf\u0026rdquo; dentro de tus funciones sin problemas.\nAl igual que las funciones, los objetos de datos también deben documentarse, y la idea es casi la misma que documentar tus funciones. Primero, abre un nuevo script de R y guárdalo dentro de la carpeta R con el nombre que quieras (mi consejo es seguir el nombre de tus datos). Luego puedes seguir la estructura presentada a continuación.\n#\u0026#39; Random values #\u0026#39; #\u0026#39; A completely useless data set. #\u0026#39; #\u0026#39; #\u0026#39; @format A data frame with 10 rows and 2 variables: #\u0026#39; \\describe{ #\u0026#39; \\item{x}{10 values from a normal distribution with mean = 0 and sd = 1} #\u0026#39; \\item{y}{10 values from a uniform distribution} #\u0026#39; ... #\u0026#39; } #\u0026#39; @source Created by the author. \u0026#34;mydf\u0026#34; Una vez que termines este proceso, puedes ejecutar devtools::document() y se creará un nuevo archivo con el nombre de tus datos dentro de la carpeta \u0026ldquo;man\u0026rdquo;. Para ver realmente el resultado de tu documentación, solo ejecuta devtools::load_all() y luego deberías poder ejecutar help(mypackage::mydf).\n¡Nunca @export un conjunto de datos!\nCrear Vignettes Los Vignettes son una parte importante del proceso de desarrollo de paquetes porque es el espacio para hacer una \u0026ldquo;guía paso a paso\u0026rdquo; de las capacidades de tu paquete. ¡Es importante destacar que puedes crear tantos vignettes como quieras!\nComenzar un nuevo Vignette es realmente simple: solo necesitas ejecutar devtools::use_vignette(\u0026quot;intro\u0026quot;). Esto creará una nueva carpeta llamada \u0026ldquo;vignettes\u0026rdquo; y, dentro de esta carpeta, podrás ver un archivo llamado \u0026ldquo;intro.Rmd\u0026rdquo;. El \u0026ldquo;intro.Rmd\u0026rdquo; es al final un archivo Rmarkdown estándar; ahora puedes crear su contenido como quieras.\nSi necesitas ayuda con el paquete rmarkdown, mi consejo es que eches un vistazo al Rmarkdown Book!\nCrear README Como la idea también es hacer que el paquete esté disponible en Github, es casi obligatorio tener una buena sección README. Pensando en eso (OTRA VEZ), el paquete usethis tiene la función usethis::use_readme_rmd() para ayudarnos a organizar nuestro archivo README. Ahora solo es cuestión de abrir el archivo creado por usethis::use_readme_rmd(), seguir la estructura e incluir lo que quieras.\n¡Recuerda Knit cada vez que cambies algo en el archivo README!\nEs buena idea mirar los repositorios de otros paquetes en Github para inspirarte.\nPara incluir las badges puedes usar el paquete usethis (ej.: usethis::use_badge(), usethis::use_cran_badge(), etc.).\nEnvío a CRAN Ahora es el momento de actualizar tu paquete en el repositorio principal de R, la Comprehensive R Archive Network, CRAN. Todo el trabajo que hemos hecho hasta ahora es esencial para que tu paquete sea aceptado en el repositorio de CRAN.\nLo primero que hay que hacer es estar en concordancia con la CRAN Repository Policy. Aquí encontrarás las reglas y pautas a seguir para que tu paquete sea alojado por CRAN. El siguiente paso es completar el formulario web.\nAlerta de Spoiler: El formulario web te pedirá que proporciones tu paquete en un archivo .tar.gz, y también ejecutarán algunas rutinas automáticas para verificar si tu paquete está en buena forma para ser revisado por alguien en CRAN. Antes de \u0026ldquo;compilar\u0026rdquo; tu paquete en formato .tar.gz, veamos si nuestro paquete pasará las pruebas automáticas de CRAN. Para simular el procedimiento de verificación de CRAN puedes ejecutar devtools::check(); debería darte una buena idea de si tu paquete está listo para ser alojado por CRAN.\nAhora que tienes un paquete con 0 errores, 0 advertencias y 0 notas, es hora de compilar el paquete en .tar.gz. La forma sencilla de hacerlo es ejecutando devtools::build() y ¡eso es todo! Tu paquete ahora está listo para ser enviado a CRAN. Sigue los pasos presentados en el formulario web y estate atento a tu correo electrónico (todas las comunicaciones sobre el estado de tu paquete serán por correo electrónico).\n¡Para la siguiente versión de tu paquete puedes usar devtools::release()!\npkgdown Ahora que nuestro paquete está disponible en Github y en CRAN, podemos crear fácilmente su propia página, ¡como un profesional! Gracias a pkgdown, es muy simple hacer una página muy bonita para difundir tu paquete a toda la comunidad de R.\nNo voy a cubrir toda la funcionalidad de pkgdown; para eso puedes ver la página de pkgdown!\nComo ya tenemos la estructura del paquete, lo único que hay que hacer para crear la página de tu paquete es:\n# Run to configure package to use pkgdown (once) usethis::use_pkgdown() # Run to build the website (every time you change it) pkgdown::build_site() ¡Te dije que esta era la parte más fácil! Ahora alojemos la página en Github Pages.\nPara ello debes entrar en el repositorio de Github de tu paquete e ir a Settings \u0026gt; GitHub Pages:\nAhora solo necesitas cambiar la Source donde estará la estructura de la página (para mí está en la rama master y dentro de la carpeta docs).\n¡pkgdown creará la carpeta docs por ti cuando ejecutes pkgdown::build_site()!\n¡Listo! Solo add, commit, push y la página de tu paquete estará en línea en: your_github_user.github.io/repository_name.\nEso es todo Espero que alguien encuentre útil este tutorial. Como siempre, tus comentarios son muy apreciados; ¡no dudes en ponerte en contacto conmigo a través de las redes sociales! 😄\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/package-development-tutorial/","summary":"\u003ch2 id=\"motivación\"\u003eMotivación\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eSi estás usando un script más de 3 veces, es hora de crear una función, y si estás usando una función en 3 proyectos diferentes, es hora de crear un paquete. \u0026ldquo;\u003cem\u003eLo escuché de alguien, pero no recuerdo de quién..\u003c/em\u003e\u0026rdquo;\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eRecientemente experimenté todo el flujo para crear un nuevo paquete de R con la ayuda de paquetes increíbles como \u003ccode\u003edevtools\u003c/code\u003e, \u003ccode\u003eusethis\u003c/code\u003e, \u003ccode\u003epkgdown\u003c/code\u003e y \u003ccode\u003eroxygen2\u003c/code\u003e. Por eso decidí escribir sobre ello mientras todavía recuerdo todos los pasos necesarios para hacer que tus funciones locales estén disponibles para la comunidad de R (CRAN y Github).\u003c/p\u003e","title":"Tutorial de Desarrollo de Paquetes"},{"content":"Motivación Se me ocurrió escribir una \u0026ldquo;guía paso a paso\u0026rdquo; sobre blogdown, primero porque fue mi primera vez usando el paquete y todavía tengo todos los pasos necesarios frescos en la mente, y segundo porque probablemente necesitaré tenerlo todo documentado si algún día decido renovar este blog. Por supuesto, hay muchísimos tutoriales excelentes sobre blogdown en internet (el libro de blogdown por ejemplo), pero tal vez alguien pueda encontrar este más fácil de alguna manera\u0026hellip;\nEste post está dividido en 3 secciones: Cómo empezar, Cómo personalizar y usar, Cómo publicar. En la primera sección encontrarás algunos consejos sobre cómo empezar el desarrollo de tu propia página usando RStudio y blogdown; la segunda sección trata sobre las funcionalidades que blogdown tiene para hacernos la vida más fácil; y la última son los pasos necesarios para publicar tu página.\nCómo empezar Lo primero que hay que hacer es install.packages(\u0026quot;blogdown\u0026quot;) para instalar el paquete blogdown. Una vez hecho esto, necesitarás instalar Hugo con blogdown::install_hugo(force = TRUE), que es el generador de sitios estáticos que usa blogdown (el parámetro force = TRUE actualizará la versión de Hugo que tengas instalada).\nAhora que todo está instalado podemos empezar el desarrollo de nuestra página. Hay dos formas de empezar: usando los Addins de RStudio o mediante líneas de comando en la consola. ¡Probemos ambas!\nPara iniciar un nuevo proyecto de blogdown en RStudio es muy fácil: solo tienes que ir al menú File \u0026gt; New Project \u0026gt; New Directory y hacer clic en la opción Website using blogdown.\nEn la segunda pantalla tendrás que elegir un nombre para la carpeta del proyecto, el subdirectorio del proyecto y la plantilla de Hugo (aquí viene la parte divertida). Hugo tiene MUCHAS plantillas disponibles aquí. Te recomiendo encarecidamente que pruebes algunas de ellas y elijas la que mejor se adapte a tus expectativas.\nDespués de elegir la plantilla de Hugo, solo necesitas hacer clic en el botón \u0026ldquo;Download\u0026rdquo; y serás redirigido al repositorio de la plantilla en Github.\nAhora solo tienes que completar el repositorio en la opción Hugo theme y hacer clic en Create Project.\nSi prefieres usar la consola (estilo de los de antes), solo necesitas ejecutar la función blogdown::new_site(theme = \u0026quot;devcows/hugo-universal-theme\u0026quot;) y completar el parámetro theme.\nEsta página fue desarrollada usando el Universal Theme\nCómo personalizar y usar Si todo salió bien, RStudio debería mostrarte una vista previa de tu sitio en la pestaña Viewer, y debería abrir un script config.toml. Dentro de la carpeta de tu proyecto, blogdown creará MUCHAS carpetas; hablaremos de eso más adelante.\nEl script config.toml te da la opción de personalizar tu sitio sin cambiar nada en el CSS, HTML o JavaScript (por supuesto, si quieres cambiar profundamente tu sitio necesitarás al menos algo de conocimiento de CSS). En este archivo encontrarás opciones para cambiar el nombre de tu sitio, imágenes, algunos colores, etc. Te animo a modificar esas opciones y ver los resultados: una vez que guardes el archivo, la pestaña Viewer actualizará tu sitio automáticamente, así podrás ver tus cambios.\nCasi todas las plantillas tienen un archivo README con algunas explicaciones sobre las funcionalidades de la plantilla; te ayudará a usar el tema correctamente (puedes encontrarlo dentro de la carpeta themes).\nLas carpetas 😖 Sé que esta estructura de carpetas puede ser muy confusa al principio; esa es una de las razones por las que decidí crear este post (porque no sé si lo recordaré todo la próxima semana).\ncarpeta content La carpeta content es donde deben almacenarse todas tus publicaciones y pestañas; cada vez que escribas una nueva publicación, esta carpeta se actualizará con el contenido de tu post. Hablaremos más sobre las nuevas publicaciones más adelante.\ncarpeta static La carpeta static es donde actualizarás todas las imágenes que quieras usar en tu página. Debes reemplazar las imágenes existentes en esta carpeta con tus propias imágenes.\nA veces es necesario limpiar la caché de tu navegador para ver la nueva imagen que acabas de cambiar, y reiniciar R desde el menú de RStudio Session \u0026gt; Restart R para verla en la pestaña Viewer.\ncarpeta themes La carpeta themes es la carpeta principal de tu plantilla; aquí puedes encontrar el archivo README, CSS, JS, HTML, y en algunos temas quizás una carpeta Example. Este es el lugar al que debes ir si quieres cambiar algunas estructuras de tu página.\nNuevas publicaciones Probablemente quieras crear nuevas publicaciones en tu página sin dolor. Con eso en mente, Yihui Xie, el responsable del paquete blogdown, creó la función blogdown::new_post() (o mediante Addins \u0026gt; New Post de RStudio).\nAntes de empezar a usarla, hay otra cosa que podemos hacer para que el proceso de creación de \u0026ldquo;nuevo post\u0026rdquo; sea aún más fácil. ¡Cambiemos algunas Global options! Para ello necesitamos modificar y guardar el archivo .Rprofile, un script que se ejecuta cada vez que se inicia tu sesión de R. Este es el comando para abrir este script: file.edit('.Rprofile'). Ahora podemos establecer algunas opciones predeterminadas para nuestras nuevas publicaciones (echa un vistazo aquí para ver las otras opciones posibles).\n# default extension and default author options(blogdown.ext = \u0026#39;.Rmd\u0026#39;, blogdown.author = \u0026#39;Your Name\u0026#39;) En mi caso elegí la extensión .Rmd porque me siento más cómodo escribiendo con ella, pero puedes, por ejemplo, elegir .md si lo prefieres. Ahora que tenemos todo configurado como queremos, empecemos con la parte de escribir el post 😰. Una vez que inicias un New Post, se creará un archivo .Rmd estándar; ahora solo se trata de escribir tu contenido.\nNo es necesario Knit el archivo; blogdown renderizará el post automáticamente cuando guardes el archivo, y podrás seguir las actualizaciones en la pestaña Viewer de RStudio.\nCómo publicar Ahora que todo está hecho en nuestra página, es hora de publicarla. Te mostraré cómo hacerlo usando Github Pages, pero por supuesto hay muchas otras opciones (solo creo que esta es la más fácil\u0026hellip;). Para publicar nuestra página solo necesitamos estos 6 pasos:\nCrear una cuenta de Github\nCrear un nuevo repositorio\nEl nombre de tu repositorio DEBE SER tu nombre de usuario de Github + .github.io (USERNAME.github.io)\nClonar este repositorio DENTRO de tu carpeta de proyecto\nEjecutar la función blogdown::build_site()\nAntes de ejecutar esta función debes cambiar la opción publishDir dentro del config.toml a la carpeta USERNAME.github.io (que es tu repositorio de Github).\npublishDir = \u0026#34;USERNAME.github.io\u0026#34; PD: Si tu config.toml no tiene esta opción, puedes crearla tú mismo.\nSubir los cambios a tu repositorio de Github En la pestaña Terminal, entra en la carpeta USERNAME.github.io usando cd. Una vez dentro de esa carpeta solo necesitas: git add, git commit -m \u0026quot;first deploy my blog\u0026quot;, git push.\nTu página estará en línea en USERNAME.github.io Eso es todo El paquete blogdown tiene MUCHAS MÁS funcionalidades que las presentadas en este post. Para aprender más al respecto te recomiendo leer el libro de blogdown.\nEspero que alguien encuentre útil este tutorial. Como siempre, tus comentarios son muy apreciados; ¡no dudes en ponerte en contacto conmigo a través de las redes sociales! 😄\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/blogdown-tutorial/","summary":"\u003ch2 id=\"motivación\"\u003eMotivación\u003c/h2\u003e\n\u003cp\u003eSe me ocurrió escribir una \u0026ldquo;guía paso a paso\u0026rdquo; sobre blogdown, primero porque fue mi primera vez usando el paquete y todavía tengo todos los pasos necesarios frescos en la mente, y segundo porque probablemente necesitaré tenerlo todo documentado si algún día decido renovar este blog. Por supuesto, hay muchísimos tutoriales excelentes sobre blogdown en internet (el \u003ca href=\"https://bookdown.org/yihui/blogdown/\"\u003elibro de blogdown\u003c/a\u003e por ejemplo), pero tal vez alguien pueda encontrar este más fácil de alguna manera\u0026hellip;\u003c/p\u003e","title":"Tutorial de Blogdown"},{"content":"Resumen GitHub: adsoncostanzifilho/TextMining\nHerramienta de Minería de Texto es una interfaz desarrollada en R que utiliza principalmente los paquetes shiny, tidytext y rtweet. La idea de esta interfaz es permitirte hacer tu propio análisis de texto usando datos de Twitter en tiempo real.\nLa herramienta está en línea en el repositorio de shinyapps en la dirección https://adsoncostanzi.shinyapps.io/TextMining/.\n¿Cómo funciona esta interfaz? La interfaz está dividida en 5 pestañas presentadas en el menú de la izquierda: Home, Search, Word Cloud, Sentiment Analysis y Topic Modeling.\nLo primero que necesitas hacer para usar toda la página es recolectar algunos datos de Twitter. Para ello, solo tienes que ir a la pestaña Search y seguir los pasos que allí se presentan.\nUna vez que hayas terminado el paso de \u0026ldquo;recolección de datos\u0026rdquo; en la pestaña Search, podrás usar las otras pestañas disponibles en el menú de la izquierda.\nPD: Encontrarás en la interfaz algunos signos de ?; al hacer clic en uno de ellos se abrirá una ventana emergente con explicaciones que te guiarán sobre cómo usar esa opción correctamente.\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/text-mining-tool/","summary":"\u003ch2 id=\"resumen\"\u003eResumen\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eGitHub:\u003c/strong\u003e \u003ca href=\"https://github.com/adsoncostanzifilho/TextMining\"\u003eadsoncostanzifilho/TextMining\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eHerramienta de Minería de Texto\u003c/strong\u003e es una interfaz desarrollada en R que utiliza principalmente los paquetes shiny, tidytext y rtweet. La idea de esta interfaz es permitirte hacer tu propio análisis de texto usando datos de Twitter en tiempo real.\u003c/p\u003e\n\u003cp\u003eLa herramienta está en línea en el repositorio de shinyapps en la dirección \u003ca href=\"https://adsoncostanzi.shinyapps.io/TextMining/\"\u003ehttps://adsoncostanzi.shinyapps.io/TextMining/\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"cómo-funciona-esta-interfaz\"\u003e¿Cómo funciona esta interfaz?\u003c/h2\u003e\n\u003cp\u003eLa interfaz está dividida en 5 pestañas presentadas en el menú de la izquierda: Home, Search, Word Cloud, Sentiment Analysis y Topic Modeling.\u003c/p\u003e","title":"Herramienta de Minería de Texto"},{"content":"Resumen GitHub: adsoncostanzifilho/soothsayeR\nSoothsayeR es una interfaz basada en la vieja broma llamada \u0026lsquo;Peter answers\u0026rsquo;..\nLa idea del juego es jugar con tus amigos haciendo preguntas cuya respuesta ya conoces, y hacerles creer que R es quien está respondiendo…\nLa aplicación demuestra lo fácil que es integrar Shiny con Javascript a través de la librería shinyjs.\nLa herramienta está en línea en el repositorio de shinyapps en la dirección https://adsoncostanzi.shinyapps.io/soothsayeR/.\n¿Cómo jugar con soothsayeR? Solo necesitas presionar el punto (.) en el teclado durante la sesión de preguntas y luego escribir la respuesta en secreto. Cuando presionas el punto en el campo de texto de la pregunta, todo lo que escribas quedará enmascarado, así puedes poner la respuesta sin que nadie se dé cuenta.\nLuego, cuando termines de escribir la respuesta, solo necesitas presionar el punto nuevamente y completar la frase de la pregunta como quieras.\nEjemplo Le dices a un amigo que está a tu lado que R puede responder cualquier pregunta. Para demostrarlo, dices que le vas a preguntar a R el color de la camisa que lleva puesta.\nEn la sesión de preguntas escribirás \u0026lsquo;.red.ase answer\u0026rsquo;, pero solo se mostrará \u0026lsquo;R please answer\u0026rsquo; en la pantalla. En el siguiente paso escribirás la siguiente pregunta: \u0026lsquo;What is the color of the t-shirt of the person next to me?\u0026rsquo;.\nHecho eso, ¡solo presiona el botón \u0026lsquo;Guess\u0026rsquo; y aparecerá la respuesta red!\n","permalink":"https://adsoncostanzifilho.github.io/es/blog/soothsayer/","summary":"\u003ch2 id=\"resumen\"\u003eResumen\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eGitHub:\u003c/strong\u003e \u003ca href=\"https://github.com/adsoncostanzifilho/soothsayeR\"\u003eadsoncostanzifilho/soothsayeR\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eSoothsayeR\u003c/strong\u003e es una interfaz basada en la vieja broma llamada \u0026lsquo;Peter answers\u0026rsquo;..\u003c/p\u003e\n\u003cp\u003eLa idea del juego es jugar con tus amigos haciendo preguntas cuya respuesta ya conoces, y hacerles creer que R es quien está respondiendo…\u003c/p\u003e\n\u003cp\u003eLa aplicación demuestra lo fácil que es integrar \u003cstrong\u003eShiny\u003c/strong\u003e con \u003cstrong\u003eJavascript\u003c/strong\u003e a través de la librería \u003cstrong\u003eshinyjs\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eLa herramienta está en línea en el repositorio de shinyapps en la dirección \u003ca href=\"https://adsoncostanzi.shinyapps.io/soothsayeR/\"\u003ehttps://adsoncostanzi.shinyapps.io/soothsayeR/\u003c/a\u003e.\u003c/p\u003e\n\u003ch2 id=\"cómo-jugar-con-soothsayer\"\u003e¿Cómo jugar con soothsayeR?\u003c/h2\u003e\n\u003cp\u003eSolo necesitas presionar el punto (.) en el teclado durante la sesión de preguntas y luego escribir la respuesta en secreto. Cuando presionas el punto en el campo de texto de la pregunta, todo lo que escribas quedará enmascarado, así puedes poner la respuesta sin que nadie se dé cuenta.\u003c/p\u003e","title":"soothsayeR"},{"content":"Adson Costanzi Filho Científico de Datos en Laboratoria Soy estadístico graduado en la Universidad Federal de Rio Grande do Sul (UFRGS), Brasil, con cerca de 7 años de experiencia en entornos de ciencia de datos. Mi trabajo se centra principalmente en el desarrollo de modelos, la minería de texto, el análisis de sentimientos, la visualización de datos y la creación de informes.\nActualmente soy Científico de Datos en Laboratoria, donde soy responsable de la gestión del pipeline de datos, aprovechando la automatización para agilizar los informes de gestión y la generación de dashboards. Mi rol gira en torno al diseño de experimentos y la implementación de modelos estadísticos y algoritmos de machine learning para mejorar la experiencia de las estudiantes e impulsar iniciativas de mejora del negocio. Trabajo a diario con R, Python, SQL, Docker y Google Cloud.\nSoy un miembro activo de la comunidad de R y el desarrollador/mantenedor del paquete CSGo, alojado en CRAN, que extrae datos de la API de Steam para Counter-Strike: Global Offensive. Puedes encontrar más proyectos en los que participo en mi GitHub.\nExperiencia Científico de Datos — Laboratoria, Remoto (oct. 2021 – actualidad) Científico de Datos Senior — Evalueserve, Viña del Mar, Chile (ene. 2021 – oct. 2021) Científico de Datos — Evalueserve, Viña del Mar, Chile (sep. 2019 – ene. 2021) Especialista en Modelado de Crédito — Renner S.A., Porto Alegre, Brasil (jun. 2019 – ago. 2019) Analista de Ciencia de Datos II — Agibank, Porto Alegre, Brasil (dic. 2018 – jun. 2019) Analista de Ciencia de Datos I — Agibank, Porto Alegre, Brasil (jul. 2018 – dic. 2018) Analista de Prevención de Fraudes — Agibank, Porto Alegre, Brasil (ago. 2017 – jul. 2018) Asistente de Ciencia de Datos — British American Tobacco, Porto Alegre, Brasil (ago. 2016 – ago. 2017) Practicante de Ciencia de Datos — British American Tobacco, Porto Alegre, Brasil (nov. 2015 – ago. 2016) Educación Licenciatura en Estadística — Universidad Federal de Rio Grande do Sul (UFRGS), Porto Alegre, Brasil (2012 – 2017) Intercambio en Estadística — Universidad de Valladolid, Valladolid, España (2014 – 2015) Habilidades técnicas R · Python · SQL · Git · CSS · SAS · Office · VBA · JavaScript (principiante)\nIdiomas Portugués (nativo) · Inglés (avanzado) · Español (avanzado)\nContacto No dudes en ponerte en contacto por correo a adsoncostanzi32@gmail.com o a través de mis redes sociales. También puedes descargar mi currículum completo (PDF).\n","permalink":"https://adsoncostanzifilho.github.io/es/about/","summary":"\u003ch2 id=\"adson-costanzi-filho\"\u003eAdson Costanzi Filho\u003c/h2\u003e\n\u003ch4 id=\"científico-de-datos-en-laboratoria\"\u003eCientífico de Datos en \u003ca href=\"https://www.laboratoria.la/\"\u003eLaboratoria\u003c/a\u003e\u003c/h4\u003e\n\u003cp\u003eSoy estadístico graduado en la Universidad Federal de Rio Grande do Sul (UFRGS), Brasil, con cerca de 7 años de experiencia en entornos de ciencia de datos. Mi trabajo se centra principalmente en el \u003cstrong\u003edesarrollo de modelos\u003c/strong\u003e, la \u003cstrong\u003eminería de texto\u003c/strong\u003e, el \u003cstrong\u003eanálisis de sentimientos\u003c/strong\u003e, la \u003cstrong\u003evisualización de datos\u003c/strong\u003e y la \u003cstrong\u003ecreación de informes\u003c/strong\u003e.\u003c/p\u003e\n\u003cp\u003eActualmente soy Científico de Datos en \u003ca href=\"https://www.laboratoria.la/\"\u003eLaboratoria\u003c/a\u003e, donde soy responsable de la gestión del pipeline de datos, aprovechando la automatización para agilizar los informes de gestión y la generación de dashboards. Mi rol gira en torno al diseño de experimentos y la implementación de modelos estadísticos y algoritmos de machine learning para mejorar la experiencia de las estudiantes e impulsar iniciativas de mejora del negocio. Trabajo a diario con \u003cstrong\u003eR\u003c/strong\u003e, \u003cstrong\u003ePython\u003c/strong\u003e, \u003cstrong\u003eSQL\u003c/strong\u003e, \u003cstrong\u003eDocker\u003c/strong\u003e y \u003cstrong\u003eGoogle Cloud\u003c/strong\u003e.\u003c/p\u003e","title":"Acerca"}]