应用用户定义的函数在 R 中的数据表中执行逐行计算

问题描述 投票:0回答:1

我正在尝试使用货币转换器函数(自定义函数)将数据表中每个订单的金额从一种特定货币转换为另一种特定货币。我有两张桌子:

  1. 订单 (dfOrders)
  2. 汇率 (dfXRate)

最终,我需要使用汇率表将每个订单的所有金额(价格、增值税和费用)从“FromCUR”货币转换为与每个订单关联的“ToCUR”货币,方法是将 FromCUR 字段与“From”匹配汇率表中的“”字段,“ToCUR”与“To”字段相同,以获得“汇率”和“操作”类型。函数中将使用操作来将订单金额乘以或除以费率。

我重新生成函数和表格的完整代码如下所示。

然而,尽管我需要转换每个订单的所有金额,但我什至无法设法转换价格作为开始。当我运行代码时,R 抛出以下错误: “switch 中的错误(利率$Action,乘法 = 金额 * 利率$Rate,除法 = 金额/利率$Rate,: EXPR 必须是长度为 1 的向量”

我知道 .SDCols 可能会有所帮助,但也不知道如何使用它。

如果有人可以修复代码或建议一种更有效的替代方法,我将不胜感激。谢谢。

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)]
r data.table user-defined-functions rowwise
1个回答
0
投票

我会这样做:

library(data.table)

convertCurrenciesWithSymbol <- function(orders, exchangeRates) {
 
  # Merge orders with exchange rates
  mergedData <- merge(orders, exchangeRates, by.x = c("FromCUR", "ToCUR"), by.y = c("From", "To"), all.x = TRUE)
  
  # currency conversion 
  mergedData[, Converted := fifelse(Action == "Multiply" & ToCUR == "EUR", 
                                    paste0(as.character(round(Price * Rate, 2)), " €"),
                                    fifelse(Action == "Divide" & ToCUR == "USD", 
                                            paste0(as.character(round(Price / Rate, 2)), " $"),
                                            paste0("No Change, Original: ", Price)
                                    )
  )]
  return(mergedData)
}

convertedOrders <- convertCurrencies(dfOrders, dfXRate)

convertedOrders

switch

library(data.table)

convertCurrenciesWithSwitch <- function(orders, exchangeRates) {
  # Merge orders and rates
  mergedData <- merge(orders, exchangeRates, by.x = c("FromCUR", "ToCUR"), by.y = c("From", "To"), all.x = TRUE)
  
  # Define a helper function for conversion
  convertWithSwitch <- function(action, toCurrency, price, rate) {
    caseKey <- paste(action, toCurrency)
    switch(caseKey,
           "Multiply EUR" = paste0(as.character(round(price * rate, 2)), " €"),
           "Divide USD" = paste0(as.character(round(price / rate, 2)), " $"),
           paste0("No Change, Original: ", price))
  }
  
  # Currency conversion
  mergedData[, Converted := mapply(convertWithSwitch, Action, ToCUR, Price, Rate)]
  return(mergedData)
}


convertedOrdersWithSwitch <- convertCurrenciesWithSwitch(dfOrders, dfXRate)
convertedOrdersWithSwitch
   FromCUR ToCUR OrderID Price VAT Fees   Rate   Action Converted
1:     AED   USD       B   200  20    2 3.6725   Divide   54.46 $
2:     GBP   USD       C   150  15    3 1.2500   Divide     120 $
3:     USD   EUR       A   100  10    1 1.0600 Multiply     106 €
© www.soinside.com 2019 - 2024. All rights reserved.