Tidyeval problem in `case_when` when using function in right side formula

669 Views Asked by At

Consider the following structure:

tmp_data <- structure(
  list(
    currency = c("EUR", "USD"),
    funding = c(50, 700)),
 class = c("tbl_df", "tbl", "data.frame"),
 row.names = c(NA, -2L))

This I'm trying to convert to EUR across the board like so:

tmp_data %>%
  dplyr::mutate(
    funding = dplyr::case_when(
      currency != "EUR" ~ yahoofinancer::currency_converter(
        from = currency, to = "EUR",
        start = lubridate::today())$adj_close * funding,
      TRUE ~ funding))

While this works when explicitly changing from = currency to from = "USD", I cannot get this to work using the currency variable na matter what quo, enquo, {{ or other tidyeval constructs come to mind (and google).

The error mostly remains

Failed to evaluate the right-hand side of formula 1.

How do I get this to work? Thanks for any pointers...

2

There are 2 best solutions below

3
Hoel On BEST ANSWER

Add rowwise()

library(tidyverse)
library(yahoofinancer)

temp_data %>% 
  rowwise() %>% 
  mutate(funding = case_when(
    currency != "EUR" ~ pull(currency_converter(from = currency, to = "EUR", start = today()), adj_close) * funding, 
    .default = funding
  ))

# A tibble: 2 × 2
# Rowwise: 
  currency funding
  <chr>      <dbl>
1 EUR          50 
2 USD         645.
0
PGSA On

The RHS of case_when() should be vectorised - i.e. your function should return a vector the same length as the number of rows, it's not run per-row, it's run once then the relevant results are extracted.

Yoiu can amend that by either forcing rowwise() evaluation or by vectorising your function using something like the map family:

tmp_data %>%
  dplyr::mutate(
    funding = dplyr::case_when(
      currency != "EUR" ~ map_dbl(`currency`, ~ yahoofinancer::currency_converter(
        from = ., to = "EUR",
        start = lubridate::today())$adj_close) * funding,
      TRUE ~ funding))