我有一个在列中缩写数值的数据集。例如,12M表示1200万,1.2k表示1200。 M和k是唯一的缩写。如何编写允许R将这些值从最低到最高排序的代码?
尽管我已经使用gsub将M转换为000,000等,但这并没有考虑小数点(150万将是1.5000000)。
答案 0 :(得分:5)
> 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)
}