将两个函数应用于相同向量的不同值

问题描述 投票:0回答:1

我有两个用于显示数字的函数:

comprss <- function(x) {
  div <- findInterval(abs(x), 
                      c(0, 1e3, 1e6, 1e9, 1e12) )  # buckets of thousands
  digits <- 2
  if (!is.null(x) && !is.na(x) && abs(x)<1) {
    x[abs(x) <  1e-07] <- 0 #very low values at 0 for display purposes
    x <- signif(x, digits)
  } else {
    paste0(signif(x/10^(3*(div-1)), 3), 
           c("","k","M","B","T")[div],sep="")
  }
}

reformat <- function(x, digits) {
  abs_x <- abs(x)
  x <- ifelse(abs_x < 0.0000001, 0, x) # Very low values set to 0 for display purposes
  x <- ifelse(abs_x >= 10^digits,
                    stringr::str_extract(as.character(formattable::comma(x)), "^[^\\.]+"),
                    signif(x, digits))
  return(x)
}

comprss
用于重写带有压缩后缀的数字(k 代表千,M 代表百万...)

reformat
用于用适当的逗号书写数字。

我有三个相同长度的向量

x
unit
digits

x <- c(1, 12, 871, 1873, 87128, 0.125, 1.1652, 321.276, 17627.17012, 1, 12, 871, 1873, 87128, 0.125, 1.1652, 321.276, 17627.17012, 1, 12, 871, 1873, 87128, 0.125, 1.1652, 321.276, 17627.17012)

unit <- c("€", "€", "€", "€", "€", "€", "€", "€", "€", "%", "%", "%", "%", "%", "%", "%", "%", "%", "pts", "pts", "pts", "pts", "pts", "pts", "pts", "pts", "pts")

digits <- c(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3)

我想将

comprss
应用于单位为
x
中的 not
c("pts","%")
的值,并重新格式化为单位为
x
中的
c("pts","%")
的值。

我的问题是这两个函数都接受

"numerical"
对象作为参数,并返回
"character"
对象。如果我将一个函数应用于某些值,它会将向量转换为字符向量,因此我无法应用另一个函数。

我创建了这个中间函数来解决我的问题:

custom_function <- function(x, unit, digits) {
  if (!(unit %in% c("%","pts"))) {
    x <- comprss(x)
  } else {
    x <- reformat(x,digits)
  }
}
    
 x <- mapply(custom_function, x, unit, digits)

它确实有效,但我重复这个操作很多次并且对巨大的数据向量,并且

mapply
非常慢。

我怎样才能以更优化的方式做到这一点?我的意思是使用更少的内存和更少的时间(我需要保持值的顺序)。

我已经问过同一个表的3列的问题,但现在不再是这样了。

r optimization memory vector time
1个回答
0
投票

您可以预先实例化一个空字符串向量,然后进行简单的索引:

out <- character(length(x)) # empty strings
out[!unit %in% c("pts", "%")] <- sapply(x[!unit %in% c("pts", "%")], comprss)
out[unit %in% c("pts", "%")] <- sapply(x[unit %in% c("pts", "%")], reformat, digits=3)
© www.soinside.com 2019 - 2024. All rights reserved.