Davis Vaughan's Avatar

Davis Vaughan

@davisvaughan.bsky.social

Building tools for R users, these days mostly in Rust ๐Ÿฆ€ https://blog.davisvaughan.com https://github.com/DavisVaughan

2,699 Followers  |  210 Following  |  107 Posts  |  Joined: 12.11.2023  |  2.6623

Latest posts by davisvaughan.bsky.social on Bluesky

- Retaining names of `x`, which is different than case_when() github.com/tidyverse/ti...

- Retaining intent / obviousness of the code via argument ordering and a more expressive name for the action (important for beginners) github.com/tidyverse/ti...

05.08.2025 16:00 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I think there are 4 reasons to have replace_when(), even if it feels like a wrapper at surface level. Taken together, I think they are convincing enough:

- Type stability, as discussed github.com/tidyverse/ti...

- Native pipe support, which I think is an underrated issue github.com/tidyverse/ti...

05.08.2025 16:00 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I also don't think the named-argument-based API is so bad in forcats, since the only type involved is character, so it's possible that could continue to exist in whatever new utils we'd create there (although I do think that has some weird edge cases with `NA` as a name, so maybe not).

05.08.2025 15:52 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

We are also exposing these utilities in a lower level package, vctrs, which has very few dependencies. My hope is that forcats can import this and use these new vctrs tools to build factor specific versions - unfortunately I think the tooling has to be there, this case is very specific to factors.

05.08.2025 15:52 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0

Is that not something like `case_when(grepl(...) ~ x, grepl(...) ~ y)`?

05.08.2025 12:01 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Honestly if thereโ€™s one example that convinces me we need replace_values(), itโ€™s watching Hadley struggle with this without it ๐Ÿ˜‚

05.08.2025 10:44 โ€” ๐Ÿ‘ 4    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I think of _values slightly differently (but close!). replace/recode_values() have dual APIs (see linked post). _values indicates you supply values on the LHS of the formula (or from/to), _when (case_when, replace_when) indicates you provide logical vectors on the LHS bsky.app/profile/davi...

05.08.2025 10:42 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Oh man, right_join(), rows_update(), multiple select()s! That is SCREAMING to all be replaced by a single call to replace_values()

05.08.2025 10:33 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

We talk about this exact case! I think you nailed it:
- It's a large mental leap for beginners
- It requires extra steps for a full column replacement
- Getting `unmatched` right is tricky when you want extra safety
github.com/tidyverse/ti...

05.08.2025 01:50 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Using the `unmatched` argument of `recode_values()` to error on unmatched values rather than falling through to `default`

Using the `unmatched` argument of `recode_values()` to error on unmatched values rather than falling through to `default`

If you've found yourself in the middle of a `case_when()` going, "oh shit, did I cover all of those cases??", then I think you'll REALLY like the new `unmatched` argument of `recode_values()`!

Here we catch a `0` that wasn't matched by any Likert score code in our lookup table.

05.08.2025 01:48 โ€” ๐Ÿ‘ 6    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
New `replace_values()` being used to collapse multiple groups into a single group within a `name` vector

New `replace_values()` being used to collapse multiple groups into a single group within a `name` vector

If you find yourself doing `x = case_when(..., .default = x)` to "partially replace" a few values within a column, I think you'll like `replace_values()`!

05.08.2025 01:43 โ€” ๐Ÿ‘ 2    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

For the life of me I canโ€™t ever remember how na_if() works. Does it turn a value into NA or NA into a value? Why canโ€™t I do na_if(x, c(-99, -98)) when I have multiple problem values?? Easily solved with:

replace_values(x, c(-99, -98) ~ NA)

05.08.2025 01:34 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Yes, replace_values() has a dual API. A from/to API and a formula API (like case_when).

So you can do either

replace_values(x, โ€œoneโ€ ~ โ€œ1โ€, โ€œtwoโ€ ~ โ€œ2โ€)

Or

replace_values(x, from = from, to = to)

Iโ€™m convinced we need both!

05.08.2025 01:30 โ€” ๐Ÿ‘ 6    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 1

The other huge limitation of named vectors is that it only works with a character lookup table - the names have to be character โ€œ1โ€ rather than numeric 1, which is what you actually want here. `score` is numeric, not character!

05.08.2025 01:25 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0

I even planned to ping you directly since `replace_values()` draws a bit of inspiration from naniar, and in theory is a swiss army knife that can do all of what `tidyr::replace_na()`, `naniar::replace_na_with()`, `naniar::replace_with_na()`, `na_if()`, and `coalesce()` do (see tidyup examples)!

04.08.2025 21:47 โ€” ๐Ÿ‘ 4    ๐Ÿ” 1    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Recoding a `score` column using a Likert scale lookup table and a new `recode_values()` function in dplyr

Recoding a `score` column using a Likert scale lookup table and a new `recode_values()` function in dplyr

If you find yourself still reaching for `dplyr::recode(x, !!!values)` or `plyr::mapvalues()`, then I think you'll like `recode_values()`!

04.08.2025 21:44 โ€” ๐Ÿ‘ 26    ๐Ÿ” 8    ๐Ÿ’ฌ 3    ๐Ÿ“Œ 1

We are looking for some community feedback on 3 new dplyr functions!

- replace_when()
- recode_values()
- replace_values()

New tools for recoding (think, lookup tables!) and replacing (think, replace `-99` with `NA` in `col`) in the tidyverse - I'm pretty excited about these!

04.08.2025 21:38 โ€” ๐Ÿ‘ 85    ๐Ÿ” 26    ๐Ÿ’ฌ 7    ๐Ÿ“Œ 0

Remember this #rstats post? I wasn't the only one talking about it & the tidyverse team was listening ๐Ÿ˜Ž #databs

New #dplyr functions? They're looking for feedback!!
๐Ÿค” replace_when, recode_values, replace_values

๐Ÿ‘€ Read this:
github.com/tidyverse/ti...

๐Ÿ—ฃ๏ธ Comment on PR:
github.com/tidyverse/ti...

04.08.2025 17:30 โ€” ๐Ÿ‘ 50    ๐Ÿ” 13    ๐Ÿ’ฌ 4    ๐Ÿ“Œ 2
A first look at Positron - Julia Silge
YouTube video by useR! Conference A first look at Positron - Julia Silge

It's the virtual day for useR! Some of the talks are already available, including this one: I always enjoy @juliasilge.com explaining things so if you are curious about the Positron IDE (it's out of beta now!), this is for you:
www.youtube.com/watch?v=aKSr... #rstats

01.08.2025 11:12 โ€” ๐Ÿ‘ 24    ๐Ÿ” 8    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
A first look at Positron - Julia Silge
YouTube video by useR! Conference A first look at Positron - Julia Silge

My @user-conf.bsky.social virtual talk, a first look at Positron for #rstats folks, posted while I was asleep ๐Ÿ˜ด but you can catch it here:
youtu.be/aKSrptGegeo?...

01.08.2025 13:44 โ€” ๐Ÿ‘ 19    ๐Ÿ” 6    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
Air, an extremely fast R formatter We are thrilled to announce Air, a new R formatter.

Okay, I saw @libbyheeren.bsky.social mention Air recently but did not realize what it was until today's Data Science Hangout. Looks very cool for formatting code!

www.tidyverse.org/blog/2025/02...

31.07.2025 16:16 โ€” ๐Ÿ‘ 18    ๐Ÿ” 5    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

The virtual useR! 2025 event is happening tomorrow (August 1). There's still time to register. Claim your spot, for free, before time runs out!

The program: user2025.r-project.org/program/virt...
Registration: user2025.r-project.org/register

#useR2025 #rstats

31.07.2025 12:05 โ€” ๐Ÿ‘ 16    ๐Ÿ” 13    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 2

Today at 12pm ET! In just under an hour!

31.07.2025 15:03 โ€” ๐Ÿ‘ 3    ๐Ÿ” 1    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Preview
Making libcurl work in webassembly We explain how to make libcurl based applications work in webassembly without changes by tunneling all traffic over a websocket proxy.

Making libcurl work in webassembly

https://jeroen.github.io/notes/webassembly-curl/

30.07.2025 12:01 โ€” ๐Ÿ‘ 25    ๐Ÿ” 10    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Making Libcurl Work in WebAssembly | Hacker News

We found a pretty neat way to make curl/httr2 work in WebR:

29.07.2025 14:15 โ€” ๐Ÿ‘ 24    ๐Ÿ” 5    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Oh I'm fairly certain it's a bug that RStudio shows `.fn = \(x) { body` in the outline but doesn't pick up on `.fn = \(x) body` without the braces. They should both show up, there is no semantic difference between the two functions. So I think you're relying on a bug ๐Ÿ˜†

28.07.2025 12:16 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Formatter โ€“ Air

You can read about when we auto brace anonymous functions here. Short one liners are allowed, everything else is auto braced. posit-dev.github.io/air/formatte...

What is the bookmarks issue? Can you show a screenshot or video?

27.07.2025 16:49 โ€” ๐Ÿ‘ 3    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
air/docs/editors.qmd at main ยท posit-dev/air R formatter and language server. Contribute to posit-dev/air development by creating an account on GitHub.

I know nothing about Emacs but if anyone wants to do a PR to add the setup workflow to our Air website, we'd be open to it! github.com/posit-dev/ai...

27.07.2025 14:45 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

For now you could copy that binary to a path that you own (not one Positron "owns"). Or work with IT to make the official installer script work to get the CLI binary the right way.

27.07.2025 14:40 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Oh I wouldn't really encourage using the bundled one in RStudio. As soon as the Air extension auto-updates itself in Positron, you'll get a new binary in a new path (like `-0.16.0/`).

27.07.2025 14:40 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

@davisvaughan is following 20 prominent accounts