将单位缩写转换为数字

时间:2019-05-16 00:02:29

标签: r units-of-measurement exponent

我有一个在列中缩写数值的数据集。例如,12M表示1200万,1.2k表示1200。 M和k是唯一的缩写。如何编写允许R将这些值从最低到最高排序的代码?

尽管我已经使用gsub将M转换为000,000等,但这并没有考虑小数点(150万将是1.5000000)。

4 个答案:

答案 0 :(得分:5)

  • 因此,您想将SI单位缩写(“ K”,“ M”,...)转换为指数,从而将其转换为十进制的幂。 假设所有单位都是单字母,并且指数是10 ** 3的均等幂,以下是处理“ Kilo” ...“ Yotta”以及所有未来指数的工作代码:
    > 10 ** (3*as.integer(regexpr('T', 'KMGTPEY')))
    [1] 1e+12

然后将十进制幂乘以您的十进制值即可。

  • 此外,您可能想检测并处理未知字母前缀的“不匹配”情况,否则您将得到荒谬的-1*3
    > unit_to_power <- function(u) {
        exp_ <- 10**(as.integer(regexpr(u, 'KMGTPEY')) *3)
        return (if(exp_>=0) exp_ else 1)
    }
  • 现在,如果您要将K和K与Kilo进行大小写不敏感匹配(计算机人经常写,尽管从技术上讲它是对SI的滥用),那么您需要特殊-case,例如,如果使用if-else梯形图/表达式(SI单位通常区分大小写,则“ M”表示“ Mega”,但即使磁盘驱动器用户另有说明,“ m”严格表示“ milli”;大写字母通常为正指数)。因此,对于一些前缀,@ DanielV的区分大小写的代码更好。

  • 如果您还需要负SI前缀,请使用as.integer(regexpr(u, 'zafpnum@KMGTPEY')-8),其中@只是一些一次性字符,用于保持均匀的间距,实际上不应该匹配。同样,如果您需要处理非10幂次幂的3个单位(例如'deci','centi'),则需要特殊外壳或WeNYoBen使用的基于字典的常规方法。

  • base::regexpr未被向量化,在大输入量时其性能也很差,因此,如果要向量化并获得更高的性能,请使用stringr::str_locate

答案 1 :(得分:3)

试一下:

Text_Num <- function(x){
    if (grepl("M", x, ignore.case = TRUE)) {
        as.numeric(gsub("M", "", x, ignore.case = TRUE)) * 1e6
    } else if (grepl("k", x, ignore.case = TRUE)) {
        as.numeric(gsub("k", "", x, ignore.case = TRUE)) * 1e3
    } else {
        as.numeric(x)
    }
}

答案 2 :(得分:1)

您可以使用gsubfn

a=c('12M','1.2k')
dict<-list("k" = "e3", "M" = "e6")
as.numeric(gsubfn::gsubfn(paste(names(dict),collapse="|"),dict,a))
[1] 1.2e+07 1.2e+03

答案 3 :(得分:0)

很高兴见到你。

我写了另一个答案

定义功能

import xml.etree.ElementTree as ET
tree = ET.parse(xml_file_path)
root = tree.getroot()
ns0 = "{http://dfg.co}"
ns1 = "{http://zyx.co}"
f_node = root.find('.//{0}f'.format(ns1))
f_node.text = '22222'
tree.write(xml_file_path)

结果

res = function (x) {
  result = as.numeric(x)
  if(is.na(result)){
  text = gsub("k", "*1e3", x, ignore.case = T)
  text = gsub("m", "*1e6", text, ignore.case = T)
  result = eval(parse(text = text))
  } 
  return(result)
}