R 优雅地将1M转换为1000000

R 优雅地将1M转换为1000000,r,data.table,R,Data.table,我想转换: library(data.table) market.cap <- data.table(cap=c("1B", "10M", "2M")) cap 1 1B 2 10M 3 2M 这是我的解决办法。它是有效的,但需要添加一个列,我知道这是不必要的。有什么更好的办法 market.cap[, cap1 := cap] market.cap$cap = sapply(market.cap$cap, function(x) (as.numeric(temp <-

我想转换:

library(data.table)
market.cap <- data.table(cap=c("1B", "10M", "2M"))

  cap
1  1B
2 10M
3  2M
这是我的解决办法。它是有效的,但需要添加一个列,我知道这是不必要的。有什么更好的办法

market.cap[, cap1 := cap]
market.cap$cap = sapply(market.cap$cap, function(x) (as.numeric(temp <- gsub("B", "", x)) * 1000000000))
market.cap$cap1 = sapply(market.cap$cap1, function(x) (as.numeric(temp <- gsub("M", "", x)) * 1000000))
M = data.frame(x = na.omit(market.cap$cap))
B = data.frame(x = na.omit(market.cap$cap1))
rbind(M,B)
market.cap[,cap1:=cap]

market.cap$cap=sapply(market.cap$cap,function(x)(as.numeric)(temp我们可以使用
gsubfn
,匹配非数字元素(
\\D
),将其替换为与
键匹配的
列表的相应
,并使用
eval(parse
)将其转换为数值

library(gsubfn) 
options(scipen=999)
unname(sapply(gsubfn('\\D', list(B= '*1e9', M= '*1e6'), 
       market.cap$cap), function(x) eval(parse(text=x))))
#[1] 1000000000   10000000    2000000

我们还可以在提取
数字部分和非数字部分后使用
匹配
,然后使用带有字母向量(
c('B','M')
)的
匹配
)来获取数字索引并用新值替换它

 market.cap[,  cap1 := as.numeric(sub('\\D', '', 
    cap))*c(1e9, 1e6)[match( sub('\\d+', '', cap), c('B', 'M'))]]
 #    cap       cap1
 #1:  1B 1000000000
 #2: 10M   10000000
 #3:  2M    2000000

这也是一种选择:

# Your toy data
library("data.table")
market.cap <- data.table(c("1B", "10M", "2M"))
colnames(market.cap) <- "cap"

# Helpful functions
ssub <- function(x) gsub("B", "*1e9", gsub("M", "*1e6", x))
evalp <- function(x) eval(parse(text = x))

# Substitute and evaluate
sapply(ssub(market.cap$cap), evalp)
#1*1e9 10*1e6  2*1e6 
#1e+09  1e+07  2e+06 
#您的玩具数据
库(“数据表”)
market.cap以下是我自己的尝试:

market.cap[ , cap1 := {
  sf <- gsub("[0-9]", "", cap)
  as.numeric(gsub("[^0-9]", "", cap)) * 1000 ^ (2 + (sf == "B"))}]
自从在
数据中优化了
tstrsplit
以来,以下可能被证明是最快的

market.cap[ , cap1 := {
  x <- tstrsplit(cap, split = "(?=[BM])", perl = TRUE)
  as.numeric(x[[1L]]) * 1000 ^ (2 + (x[[2]] == "B"))}]
market.cap[,cap1:={

x除了B和M之外还有其他的吗?如果没有,那么可能
带有(market.cap,as.numeric(sub(“\\D+”,“”,cap))*ifelse(grepl(“B”,cap),1e9,1e6))
@Richard Scriven,不,只有B和M。这很有效。也许可以作为答案发布?一些业余问题:它看起来像
\\D
,与
\\D+
一样有效?我对两者都不熟悉,有什么区别吗?如果
with
的第二个参数删除了
B
M
,那么第三个参数如何处理搜索
B
的ment可能会找到它?它不是刚刚被删除了吗?protip:
market.cap事实上,为我使用
colnames
会立即导致问题,出现无效的
.internal.selfref
错误。因此,我编辑了你的问题。你是正确的,好先生!microbenchmark的平均时间:解决方案一:28.16288,解决方案二:17.26301,解决方案三:12.63196。感谢您的帮助和上面的提示。
market.cap[ , cap1 := {
  x<- do.call("rbind", strsplit(cap, split = "(?=[BM])", perl = TRUE))
  as.numeric(x[ , 1L]) * 1000 ^ (2 + (x[ , 2L] == "B"))}]
market.cap[ , cap1 := {
  x <- tstrsplit(cap, split = "(?=[BM])", perl = TRUE)
  as.numeric(x[[1L]]) * 1000 ^ (2 + (x[[2]] == "B"))}]