1

Given the following, from 1 USD to

  • euro
  • peso
  • franc
  • Australian dollar
  • New Zealand dollar
  • Canadian dollar

How would I write a function to convert from one currency to another?

The function should work like this - amount is numeric, from and to are character strings:

currency(amount = 1, from = 'usd', to = 'euro')
## [1] 8.7

The only thing I can think if is to write numerous if statements, but that seems way too tedious for all these possibly currency conversions/combinations.

I'm also thinking of creating a named vector in my function like so: c('euro' = 0.93, 'peso' = 24.71, 'franc' = 0.98, ...) and so on to show the conversion rates from 1 USD to these currencies. But still not sure how to write a function that accounts for all these currency conversions (USD, euro, peso, franc, Austrian dollar, New Zealand dollar, Canadian dollar).

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Taylor
  • 13
  • 1
  • 6
  • Nice question, a fun task - I wouldn't have immediately thought of the named vector as a route, just because I never seem to use them, but decided to go that way and see what I came up with! :) – rg255 Apr 23 '20 at 21:17
  • Also see thread here for how to get up to date currency rates: https://stackoverflow.com/questions/26694042/how-to-get-currency-exchange-rates-in-r – Bryan Shalloway May 14 '21 at 20:59

2 Answers2

1

Here is a function, it does suffer from slight rounding error but just needs numbers with greater resolution to reduce that error - my values come from google searches of 10000 USD in each currency. You could also look at packages that scrape values from the web (rvest?) if you want to keep values updated automatically.

currencyCon <- function(x, from = "USD", to = "EUR"){
  # assign values: 1 usd in each currency 
  values <- c(1.000000, 0.927985, 0.810100, 107.624500)
  # names attribute 
  names(values) <- c("USD", "EUR", "GBP", "YEN")
  # calculate (convert from into USD, and divide to)
  values[to] / (values[from] / x)
}

# Testing 
currencyCon(1, "USD", "EUR")
currencyCon(1, "EUR", "EUR")
currencyCon(1, "GBP", "YEN")

This returns

 > currencyCon(1, "USD", "EUR")
 EUR 
 0.927985
 > currencyCon(1, "EUR", "EUR")
 EUR 
 1 
 > currencyCon(1, "GBP", "YEN")
 YEN 
 132.8534
rg255
  • 4,119
  • 3
  • 22
  • 40
  • Thank you! Is there a specific reason why you set default values for `from` as `"USD"` and `to` as `"EUR"`? – Taylor Apr 23 '20 at 22:46
  • Also, in the final output how do you just display the number (without the currency)? For example, displaying this: `0.927985` instead of this: `EUR` `0.927985` – Taylor Apr 23 '20 at 22:58
  • defaults were chosen just for the sake of it, to remove them use `currencyCon <- function(x, from, to){ ... ` and to get rid of the name attribute on the output change the calculation to `as.numeric(values[to] / (values[from] * x))`. PS if this answers your question please accept the answer (plus an upvote if you feel generous) – rg255 Apr 24 '20 at 04:04
  • Thank you! I just accepted the answer and upvoted (but it said upvote won't be publicly shown). When I invoke `currencyCon(x=10, from='USD', to='EUR')`, it yields `0.0927985` when the answer is actually 100 times that. Why does this function work correctly only when `x=1`, and with values other than `x=1` it shows the wrong currency conversion? – Taylor Apr 24 '20 at 08:01
  • Apologies - should be `/x` not `*x` - updated answer – rg255 Apr 24 '20 at 09:30
1

Below is just a slight modification on rg255's answer. You can use {quantmod} or other packages to ensure your currency conversion rates are up to date (see thread).

library(quantmod)
library(tidyverse)

possible_countries <- c("USD", "EUR", "GBP", "JPY")

rates <- tibble(from = "USD", 
                       to = possible_countries) %>% 
  mutate(getQuote(paste0(from, to, "=X")) %>% 
           select(rate = Last))

currencyCon <- function(x, 
                        from = "USD", 
                        to = "EUR", 
                        lookup = rates){
  # assign values: 1 usd in each currency 
  values <- lookup$rate
  # names attribute 
  names(values) <- lookup$to
  # calculate (convert from into USD, and divide to)
  values[to] / (values[from] / x)
}

crossing(from = possible_countries, 
         to = possible_countries) %>% 
  mutate(start_amount = 10) %>% 
  mutate(amount_converted = currencyCon(start_amount, from, to))
#> # A tibble: 16 x 4
#>    from  to    start_amount amount_converted
#>    <chr> <chr>        <dbl>            <dbl>
#>  1 EUR   EUR             10          10     
#>  2 EUR   GBP             10           8.61  
#>  3 EUR   JPY             10        1328.    
#>  4 EUR   USD             10          12.1   
#>  5 GBP   EUR             10          11.6   
#>  6 GBP   GBP             10          10     
#>  7 GBP   JPY             10        1542.    
#>  8 GBP   USD             10          14.1   
#>  9 JPY   EUR             10           0.0753
#> 10 JPY   GBP             10           0.0649
#> 11 JPY   JPY             10          10     
#> 12 JPY   USD             10           0.0915
#> 13 USD   EUR             10           8.23  
#> 14 USD   GBP             10           7.09  
#> 15 USD   JPY             10        1093.    
#> 16 USD   USD             10          10

Created on 2021-05-14 by the reprex package (v2.0.0)

Bryan Shalloway
  • 748
  • 7
  • 15