I’m trying to use a Currency Converter function (custom function) to convert amounts of each Order in a data table from one specific currency to another. I have two tables:
- Orders (dfOrders)
- Exchange Rates (dfXRate)
Ultimately, I need to convert all amounts for each order (Price, VAT, and Fees) from the “FromCUR” currency to the “ToCUR” currency associated with each order using the Exchange Rate table by matching the FromCUR field to the “From” field in the Exchange Rate table, and the same for the “ToCUR” with the “To” field to get the “Rate” and the “Action” type. Action will be used in the function to either Multiply or Divide the Amount from the Order by the Rate.
My complete code to re-produce the Function and tables is shown below.
Yet, I could not even manage to convert the Price as a start although I need to convert all amounts for each order. When I run the code, R throws the following error: “Error in switch(rate$Action, Multiply = Amount * rate$Rate, Divide = Amount/rate$Rate, : EXPR must be a length 1 vector”
I’m aware that .SDCols might help here, but not sure how to use it either.
Would be grateful if someone can fix the code or suggest an alternative more efficient one. Thanks.
CurConverter <- function(FromCUR, ToCUR, Amount, exchange_rate_table) {
# Look up exchange rate from the provided table
rate <- exchange_rate_table[From == FromCUR & To == ToCUR, .(Rate, Action)]
# if (nrow(rate) == 0) {
# warning("Exchange rate not found for the specified currencies. Returning original amount.")
# return(Amount)
# }
result <- switch(rate$Action,
Multiply = Amount * rate$Rate,
Divide = Amount / rate$Rate,
Amount) |>
as.numeric()
return(result)
}
# Example data tables
dfOrders <- data.table(
OrderID=c("A","B","C"),
FromCUR = c("USD", "AED", "GBP"),
ToCUR = c("EUR", "USD", "USD"),
Price = c(100, 200, 150),
VAT=c(10,20,15),
Fees=c(1,2,3)
)
dfXRate <- data.table(
From = c("USD", "AED", "GBP"),
To = c("EUR", "USD", "USD"),
Rate = c(1.06, 3.6725, 1.25),
Action = c("Multiply", "Divide", "Divide")
)
# Merge data tables based on currency columns
merged_df <- merge(dfOrders, dfXRate, by.x = c("FromCUR", "ToCUR"), by.y = c("From", "To"), all.x = TRUE)
# Apply the CurConverter function to each row
merged_df[, ConvertedPrice := CurConverter(FromCUR, ToCUR, Price, dfXRate)]
Here is how I would do it:
With
switch