【问题标题】:R fractions with library(MASS)R 分数与图书馆(MASS)
【发布时间】:2016-02-24 16:47:00
【问题描述】:

我有一长串字符格式的数字(大约 50000 个术语),可以使用“as.numeric”快速转换为数字:

y = c("-1", "1", "1", ...)

问题是我已经扩展了功能以包括分数和调用

    y = c("-1/2", "1", "1", ...)
    y = as.numeric(y);

在调用时产生“强制引入的 NAs”警告消息

 sapply(y , function(x) {

     eval(parse(text=x));
  });

解决了问题,但执行时间要长得多。有没有更好的方法来做到这一点?

【问题讨论】:

  • 你可以试试sapply(y, function(x) if(grepl('/', x)) eval(parse(text=x)) else as.numeric(x))

标签: r fractions


【解决方案1】:

eval(parse(text)) 很慢——你知道你会做什么,你可以写一个更快的函数:

y = c("-1/2", "1", "1", "1/2")
fixnums <- function(x){
  temp <- as.numeric(x)
  temp[is.na(temp)] <- lapply(strsplit(x[is.na(temp)], "/"), function(x) as.numeric(x[1])/as.numeric(x[2]))
  unlist(temp)
}
fixnums(y)

@DavidArenburg 在下面的评论中建议的更快的版本,避免 lapply:

davidfixnums <- function(x){
  temp <- as.numeric(x)
  temp2 <- as.numeric(unlist(strsplit(y[is.na(temp)], "/", fixed = TRUE)))
  temp[is.na(temp)] <- temp2[c(T, F)]/temp2[c(F, T)]
  temp
}

一些基准测试,使用@akrun 和@DavidArenburgs 的建议:

library(microbenchmark)
set.seed(1234)
y <- sample(c("-1/2", "1", "1", "1/2"), 10000, replace = TRUE)

akrunfixnums <- function(y){
  x1 <- as.numeric(y)
  x1[is.na(x1)] <- vapply(y[is.na(x1)], function(x) 
    eval(parse(text=x)), numeric(1))
  x1
}

microbenchmark(fixnums(y), davidfixnums(y), akrunfixnums(y))

Unit: milliseconds
            expr        min         lq       mean     median        uq       max neval cld
      fixnums(y)  22.643745  23.157345  25.326465  23.435554  23.98544 154.16316   100  b 
 davidfixnums(y)   6.676234   6.778378   6.957626   6.824459   6.93025  10.12763   100 a  
 akrunfixnums(y) 845.404840 858.031737 869.886625 865.255363 875.54351 960.86497   100   c

【讨论】:

  • 您可能会矢量化您的第二步,并在每个步骤中使用temp2 &lt;- as.numeric(unlist(strsplit(y[is.na(temp)], "/", fixed = TRUE))) ; temp[is.na(temp)] &lt;- temp2[c(T, F)]/temp2[c(F, T)]避免lapply 和双重as.numeric
  • 不错,提速 4 倍 @DavidArenburg
  • 我想知道是否将is.na(temp) 保存在一些额外的临时变量中而不是计算两次会进一步加快速度。虽然我不知道这会如何影响记忆。
猜你喜欢
  • 2016-02-05
  • 2022-07-20
  • 1970-01-01
  • 1970-01-01
  • 2011-08-05
  • 2015-05-27
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多