Found 1999 bookmarks
Newest
Describe R Stuff to Large Language Models
Describe R Stuff to Large Language Models
Provides a number of utilities for describing R objects and package documentation in plain text. For interactive use, this is especially powerful for describing relevant pieces of context to large language models. When used programmatically, these utilities can be registered with ellmer chats as tool calls, enabling language models to peruse package documentation and explore your computational environment.
·posit-dev.github.io·
Describe R Stuff to Large Language Models
Standalone shiny application with nhyris
Standalone shiny application with nhyris
Transform your R Shiny applications into standalone desktop apps with nhyris. This minimal framework leverages Electron to simplify packaging and distribution, ensuring your Shiny apps are cross-platform and easy to deploy. Learn how to get started, customize your project, and build your first Electron application with nhyris.
·blog.jahnen.io·
Standalone shiny application with nhyris
Three experiments in LLM code assist with RStudio and Positron - Tidyverse
Three experiments in LLM code assist with RStudio and Positron - Tidyverse
We've been experimenting with LLM-powered tools to streamline R data science and package development.
Twice a year, the tidyverse team sets a week aside for “spring cleaning,” bringing all of our R packages up to snuff with the most current tooling and standardizing various bits of our development process. Some of these updates can happen by calling a single function, while others are much more involved. One of those more involved updates is updating erroring code, transitioning away from base R (e.g.  stop()), rlang (e.g.  rlang::abort()), glue, and homegrown combinations of them. cli’s new syntax is easier to work with as a developer and more visually pleasing as a user.
In some cases, transitioning is almost as simple as Finding + Replacing rlang::abort() to cli::cli_abort():
# before: rlang::abort("`save_pred` can only be used if the initial results saved predictions.") # after: cli::cli_abort("{.arg save_pred} can only be used if the initial results saved predictions.")
In others, there’s a mess of ad-hoc pluralization, paste0()s, glue interpolations, and other assorted nonsense to sort through:
Thus was born clipal1, a (now-superseded) R package that allows users to select erroring code, press a keyboard shortcut, wait a moment, and watch the updated code be inlined in to the selection.
clipal was a huge boost for us in the most recent spring cleaning. Depending on the code being updated, these erroring calls used to take 30 seconds to a few minutes. With clipal, though, the model could usually get the updated code 80% or 90% of the way there in a couple seconds. Up to this point, irritated by autocomplete and frustrated by the friction of copying and pasting code and typing out the same bits of context into chats again and again, I had been relatively skeptical that LLMs could make me more productive. After using clipal for a week, though, I began to understand how seamlessly LLMs could automate the cumbersome and uninteresting parts of my work.
clipal itself is now superseded by pal, a more general solution to the problem that clipal solved. I’ve also written two additional packages like pal that solve two other classes of pal-like problems using similar tools, ensure and gander. In this post, I’ll write a bit about how I’ve used a pair of tools in three experiments that have made me much more productive as an R developer
After using clipal during our spring cleaning, I approached another spring cleaning task for the week: updating testing code. testthat 3.0.0 was released in 2020, bringing with it numerous changes that were both huge quality of life improvements for package developers and also highly breaking changes. While some of the task of converting legacy unit testing code to testthat 3e is relatively straightforward, other components can be quite tedious. Could I do the same thing for updating to testthat 3e that I did for transitioning to cli? I sloppily threw together a sister package to clipal that would convert tests for errors to snapshot tests, disentangle nested expectations, and transition from deprecated functions like ⁠expect_known_*(). ⁠(If you’re interested, the current prompt for that functionality is here.) That sister package was also a huge boost for me, but the package reused as-is almost every piece of code from clipal other than the prompt. Thus, I realized that the proper solution would provide all of this scaffolding to attach a prompt to a keyboard shortcut, but allow for an arbitrary set of prompts to help automate these wonky, cumbersome tasks.
The next week, pal was born. The pal package ships with three prompts centered on package development: the cli pal and testthat pal mentioned previously, as well as the roxygen pal, which drafts minimal roxygen documentation based on a function definition. Here’s what pal’s interface looks like now:
ensure
While deciding on the initial set of prompts that pal would include, I really wanted to include some sort of “write unit tests for this function” pal. To really address this problem, though, requires violating two of pal’s core assumptions:
All of the context that you need is in the selection and the prompt. In the case of writing unit tests, it’s actually pretty important to have other pieces of context. If a package provides some object type potato, in order to write tests for some function that takes potato as input, it’s likely very important to know how potatoes are created and the kinds of properties they have. pal’s sister package for writing unit tests, ensure, can thus “see” the rest of the file that you’re working on, as well as context from neighboring files like other .R source files, the corresponding test file, and package vignettes, to learn about how to interface with the function arguments being tested.
The LLM’s response can prefix, replace, or suffix the active selection in the same file. In the case of writing unit tests for R, the place that tests actually ought to go is in a corresponding test file in tests/testthat/. Via the RStudio API, ensure can open up the corresponding test file and write to it rather than the source file where it was triggered from.3
gander
·tidyverse.org·
Three experiments in LLM code assist with RStudio and Positron - Tidyverse
Format SQL Queries
Format SQL Queries
A convenient interface for formatting SQL queries directly within R. It acts as a wrapper around the sql_format Rust crate. The package allows you to format SQL code with customizable options, including indentation, case formatting, and more, ensuring your SQL queries are clean, readable, and consistent.
·dataupsurge.github.io·
Format SQL Queries
Metrics
Metrics
An image generator with 20+ metrics about your GitHub account such as activity, community, repositories, coding habits, website performances, music played, starred topics, etc. that you can put on your profile or elsewhere !
·metrics.lecoq.io·
Metrics
Documenting functions
Documenting functions
The basics of roxygen2 tags and how to use them for documenting functions.
Examples @examples provides executable R code showing how to use the function in practice. This is a very important part of the documentation because many people look at the examples before reading anything. Example code must work without errors as it is run automatically as part of R CMD check. For the purpose of illustration, it’s often useful to include code that causes an error. You can do this by wrapping the code in try() or using \dontrun{} to exclude from the executed example code. For finer control, you can use @examplesIf: #' @examplesIf interactive() #' browseURL("https://roxygen2.r-lib.org")
Instead of including examples directly in the documentation, you can put them in separate files and use @example path/relative/to/package/root to insert them into the documentation. All functions must have examples for initial CRAN submission.
·roxygen2.r-lib.org·
Documenting functions
AI-Powered Development: A Practical Guide for Software Engineers
AI-Powered Development: A Practical Guide for Software Engineers
Artificial Intelligence (AI) is no longer a distant future technology; it’s here and it’s reshaping software engineering. Tools like GitHub Copilot and ChatGPT are accelerating the development…
Impact of AI on Developer Productivity: Faster development cycles: Code suggestions and automation reduce time spent on repetitive tasks. Improved code quality: AI tools identify bugs or security risks that may go unnoticed by manual reviews. Enhanced learning: Engineers can receive real-time feedback or even ask AI for code explanations to learn new patterns or frameworks.
GitHub Copilot is a game-changer for writing code. Powered by OpenAI’s Codex model, Copilot suggests lines of code based on the context of what you’re writing. It’s especially useful when you’re working with repetitive tasks or writing boilerplate code.
ChatGPT, an AI chatbot developed by OpenAI, is not just a tool for casual conversations. It can be used to ask technical questions, explain difficult code, or even generate ideas for solving specific coding problems. Developers often use it for quick consultations — whether it’s about debugging or understanding the intricacies of a particular algorithm.
AI-Assisted System Architecture and Design As AI becomes more sophisticated, it may start to play a role in designing system architectures. Currently, system design is one of the more complex tasks that engineers handle, requiring a deep understanding of the trade-offs between different architectural patterns (monolithic vs. microservices, synchronous vs. asynchronous communication, etc.). Future AI tools could help design optimal architectures by analyzing the specific needs of a project, performance goals, and scalability requirements. AI could suggest which patterns, frameworks, or technologies are best suited for a given application. It could even generate architecture diagrams, API designs, or database schemas based on historical data from similar projects. This would revolutionize system design, making it faster and more accessible to engineers of all levels. While experienced architects would still be needed to make judgment calls, AI could drastically reduce the time spent on initial design phases, especially in large and complex systems.
·medium.com·
AI-Powered Development: A Practical Guide for Software Engineers
Making Tables Shiny: DT, formattable, and reactable
Making Tables Shiny: DT, formattable, and reactable
Demo of popular packages for generating interactive tables suitable for Shiny apps
formattable Another nice table-making package is formattable. The cute heatmap-style colour formatting and the easy-to-use formatter functions make formattable very appealing. color_tile() fills the cells with a colour gradient corresponding to the values color_bar() adds a colour bar to each cell, where the length is proportional to the value The true_false_formatter() defined below demonstrates how to define your own formatting function, in this case formatting TRUE, FALSE and NA as green, red and black.
If you want the features of both DT and formattable, you can combine them by converting the formattable() output to as.datatable(), and much of the formattable features will be preserved.
However, one problem I had was that when using DT::datatable, missing values (NA) are left blank in the display (which I prefer), but in the converted from formattable() version, NA’s are printed. Also, color_bar columns seem to be converted to character, which can no longer be sorted numerically.
reactable Next I tried reactable, a package based on the React Table library.
Columns are customised via the columns argument, which takes a named list of column definitions defined using colDef(). These include format definitions created using colFormat.
In the end, I used DT::datatable() in my Shiny app, because I found it the easiest, fastest, and most comprehensive. I’ve been able to achieve most of the features I wanted using just DT.
Heatmap-like fill effect:
apply the formatStyle() function to the output of datatable() to set the backgroundColor for selected columns:
Abbreviate long cells
Sometimes some cells have a large amount of text that would mess up the table layout if I showed it all. In these cases, I like to abbreviate long values and show the full text in a tooltip. To do this, you can use JavaScript to format the column to show a substring with “…” and the full string in a tooltip (<span title="Long string">Substring...</span) when values are longer than N characters (in this case 10 characters). You can do this using columnDefs and pass JavaScript with the JS() function:
Really plain table Sometimes I don’t need any of the faff. Here’s how to get rid of it all:
headerCallbackRemoveHeaderFooter <- c( "function(thead, data, start, end, display){", " $('th', thead).css('display', 'none');", "}" )
datatable( my_pic_villagers, options = list( dom = "t", ordering = FALSE, paging = FALSE, searching = FALSE, headerCallback = JS(headerCallbackRemoveHeaderFooter) ), selection = 'none', callback = JS( "$('table.dataTable.no-footer').css('border-bottom', 'none');" ), class = 'row-border', escape = FALSE, rownames = FALSE, filter = "none", width = 500 )
·clarewest.github.io·
Making Tables Shiny: DT, formattable, and reactable
rstudio/shiny: Easy interactive web applications with R
rstudio/shiny: Easy interactive web applications with R
Easy interactive web applications with R.
Compared to event-based programming, reactivity allows Shiny to do the minimum amount of work when input(s) change, and allows humans to more easily reason about complex MVC logic.
An attractive default look based on Bootstrap which can also be easily customized with the bslib package or avoided entirely with more direct R bindings to HTML/CSS/JavaScript.
Tools for improving and monitoring performance, including native support for async programming, caching, load testing, and more.
·github.com·
rstudio/shiny: Easy interactive web applications with R
Shiny - Stop-Trigger-Delay
Shiny - Stop-Trigger-Delay
Shiny is a package that makes it easy to create interactive web apps using R and Python.
observeEvent() is used to perform an action in response to an event eventReactive() is used to create a calculated value that only updates in response to an event
observe() and reactive() functions automatically trigger on whatever they access observeEvent() and eventReactive() functions need to be explicitly told what triggers them
And where does isolate fit in all this? isolate() is used to stop a reaction observeEvent() is used to perform an action in response to an event eventReactive() is used to create a calculated value that only updates in response to an event
·shiny.posit.co·
Shiny - Stop-Trigger-Delay
UNCHARTED DATA: Automating Workflows with GitHub Actions
UNCHARTED DATA: Automating Workflows with GitHub Actions
How to automate data collection and app deployment with GitHub Actions.
Create .Renviron file Within the get_data.R script of my repository, I extract my EIA API key from my R environment so that I can connect to the EIA API and pull the data needed for my project. In order for this to occur during my workflow, I need to create an .Renviron file within my virtual environment and store the key within that environment. - name: Create and populate .Renviron file run: | echo EIA_API_KEY="$EIA_API_KEY" >> ~/.Renviron shell: bash
·uncharteddata.netlify.app·
UNCHARTED DATA: Automating Workflows with GitHub Actions