在R中将货币字符串转换为数字

时间:2018-11-01 20:32:11

标签: r

尊敬的StackOverflow社区, 我现在正在研究一种方法,可以将存储为字符的货币数据向量转换为数字向量,并能够将货币转换为另一种货币。

所以想象我的载体是:

x <- c("$5M", "€10B", "CHF5K")

我想将其转换为十亿美元,所以结果应该是(考虑随机货币汇率):

x <- c(5,11000,0.4)

我为此创建了两个函数,从而开发了一种解决方案,我的第一个函数删除了成千上万,十亿和数百万个字符并对其进行了转换:

convMK <- function(cats){
for(i in 1:length(cats)){
  if(grepl("M",cats[i])==TRUE){
    cats[i] <- gsub("M","",cats[i])
  } else if(grepl("K",cats[i])==TRUE){
    temp <- "0."
    cats[i] <- gsub("K","",cats[i])
    cats[i] <-paste0(temp,cats[i])
  } else if(grepl("B",cats[i])==TRUE){
    temp <- "00"
    cats[i] <- gsub("B","",cats[i])
    cats[i] <-paste0(cats[i],temp)
    cats[i] <- gsub("\\.","",cats[i])
  } else{}
}
  return(cats)
}

第二个考虑汇率的因素将其转换为数字:

convCurr2 <- function(cats) {
  catsNum <- c(0)
  for (i in 1:length(cats)) {
    if (grepl("\\$", cats[i]) == TRUE) {
      cats[i] <- gsub("\\$", "", cats[i])
      catsNum[i] <- as.numeric(cats[i])
      catsNum[i] <- catsNum[i] * exUSD
    } else if (grepl("\\€", cats[i]) == TRUE) {
      cats[i] <- gsub("\\€", "", cats[i])
      catsNum[i] <- as.numeric(cats[i])
      catsNum[i] <- catsNum[i] * exEUR
    } else if (grepl("CA", cats[i]) == TRUE) {
      cats[i] <- gsub("CA", "", cats[i])
      catsNum[i] <- as.numeric(cats[i])
      catsNum[i] <- catsNum[i] * exCA
    } else if (grepl("\\£", cats[i]) == TRUE) {
      cats[i] <- gsub("£", "", cats[i])
      catsNum[i] <- as.numeric(cats[i])
      catsNum[i] <- catsNum[i] * exGBP
    } else if (grepl("\\CHF", cats[i]) == TRUE) {
      cats[i] <- gsub("CHF", "", cats[i])
      catsNum[i] <- as.numeric(cats[i])
      catsNum[i] <- catsNum[i] * exCHF
    }
  }
  return(catsNum)
}

然后我将按以下顺序运行函数:

cats<-convMK(cats)
cats <- convCurr2(cats)

我现在的问题是:难道没有更简单,更短的方法吗?因为这似乎太复杂了!尤其是因为我仍然没有实现该问题的解决方案,因此该功能还应该查询给定日期的正确汇率。

我非常想知道您的答案,我只是在一周前才开始学习R,作为一名市场营销专业的学生,​​我没有那么多的编码经验(意思是:没有)。因此,我渴望学习编写更优雅的代码:)

1 个答案:

答案 0 :(得分:1)

我认为只需对其向量化,就不需要循环。

multiplier <- recode(gsub('.*([[:alpha:]]+)$', '\\1', x),
                     K = 1e3,
                     M = 1e6,
                     B = 1e9,
                     .default = NA_real_)
multiplier
# [1] 1e+06 1e+09 1e+03

这是类似“ BMK”的单位。默认值为NA,因为其他任何内容都表明您不具备应有的能力。

currency <- gsub('^([^-0-9.]*)[-0-9.].*', '\\1', x)
currency
# [1] "$"   " "   "CHF"

空白是如何呈现...可能需要更多工作来处理unicode。

xnum <- as.numeric(gsub('[^-0-9.]', '', x))
xnum
# [1]  5 10  5

这将以“ 1s”(而不是数百万)的价格提供给您:

xnum * multiplier # all in "1" units
# [1] 5e+06 1e+10 5e+03

根据计算或打印输出时所需的内容,可以很容易地进行校正:

xnum * multiplier / 1e6
# [1] 5e+00 1e+04 5e-03

这时,您需要的只是转换为USD。您应该可以像执行recode(currency, ...)一样进行类似multiplier的操作,然后将xnum乘以该转换因子即可。