R包中的mapply vs loop

时间:2017-10-29 13:27:57

标签: r loops r-package mapply

我写了一个简单的函数,将旧的日文文本转换为现代形式。我想发布一个包,但我试图以两种方式改进它。首先,使用mapply而不是循环有一个小的速度增益,但我无法得到我想要的结果。这是工作循环。

normalize <- function(doc)
{
  kanji_conversion <- data.frame("old" =c("學","勲"), "new" =c("学","勳"), stringsAsFactors = FALSE)
  for (i in 1:nrow(kanji_conversion))
 {doc <- gsub(kanji_conversion$old[i], kanji_conversion$new[i], doc)
  }
  return(doc)
} 

效果很好,它位于https://github.com/histmr/Rekishi

但我对mapply版本的尝试不返回单个字符串,而是返回与kanji_conversion的nrow()匹配的向量,每个元素中有一个更改

doc <- "學"
kanji_conversion <- data.frame("old" =c("學","勲"), "new" =c("学","勳"), stringsAsFactors = FALSE)
mapply(gsub, kanji_conversion$old, kanji_conversion$new, doc)
library(stringr)
mapply(str_replace_all, kanji_conversion$old, kanji_conversion$new, doc)

有没有办法使用mapply迭代覆盖对象doc的单个版本,就像在循环中一样?

其次,在该函数的实际版本中,kanji_conversion数据帧将为2416 x 2.我是否应该在函数中包含更大的df,如示例2 x 2 df?或者它应该是外部文件?文件大小是否有“最佳实践”阈值?

1 个答案:

答案 0 :(得分:1)

长线将是你必须在提交时向CRAN解释的东西,所以最好让它们被包裹起来。此外,如果您正在制作包,则无需在函数中构建数据框。这是一个不必要的开销。倒数第二,stringi::stri_replace_all_fixed()patternreplacement参数上进行矢量化,因此您可以获得C ++支持的超快速,编码友好的帮助程序,以满足您的目的。最后,normalize_kanji()可能是避免命名冲突的函数的更好名称。

此外,您将获得其他CRAN检查警告,特别是:

  

便携包必须在其R代码中仅使用ASCII字符,除非在注释中。对其他字符使用\uxxxx转义符。

您需要与CRAN协商,将它们转换为unicode转义序列或将数据帧存储为R数据文件。

你会找到所有^^(除了那个CRAN检查警告的修复;-) https://github.com/histmr/Rekishi/pull/1,因为翻译表太大而无法放在这里。

您以前的normalize()功能现在是:

normalize_kanji <- function(doc) {
  stri_replace_all_fixed(
    doc,
    kanji_conversion_table$old,
    kanji_conversion_table$new,
    vectorize_all = FALSE
  )
}

normalize_kanji("亞啞惡蘆鰺壓菴桉")

返回

## [1] "亜唖悪芦鯵圧庵案"

这不是衡量速度的最佳方法(更多样化的输入采样会更好,但这是特定转换的速度:

microbenchmark::microbenchmark(ƒ = normalize_kanji("亞啞惡蘆鰺壓菴桉"))
## Unit: microseconds
##  expr     min     lq     mean   median       uq     max neval
##     ƒ 188.362 190.61 202.7352 193.7235 201.9745 448.688   100

如果您想与您的方法进行比较。