【问题标题】:Converting a currency string to a numeric in R将货币字符串转换为 R 中的数字
【发布时间】:2018-11-01 20:32:11
【问题描述】:

尊敬的 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,作为一名市场营销专业的学生,​​我没有那么多编码经验(意思是:没有)。因此,我渴望学习编写更优雅的代码:)

【问题讨论】:

标签: r


【解决方案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

此时,您只需要兑换成美元即可。您应该能够像我对multiplier 所做的那样执行recode(currency, ...) 之类的操作,然后将xnum 乘以这个转换因子。

【讨论】:

  • 真是天才!谢谢你的时间和回答:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 2017-06-30
  • 2012-12-19
相关资源
最近更新 更多