由于我的输入经常是德语,但我希望代码是纯英语,我希望有一个简短的自定义词典 - 基本上包括工作日和月份缩写。因此,我想创建一个快速的英语 - 德语(反之亦然)字典 - 理想情况下是parent environment = .GlobalEnv
的环境。
但是,当我将代码放入函数中时,dict_g2e
字典不再为人所知。
set_dict <- function() { # Delete this line and ...
dict_g2e <- new.env(hash = TRUE, size = 7)
from <- c("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
to <- c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat")
for (i in 1:19) {
assign(x = from[i], value = to[i], envir = dict_g2e)
} # this line and the code is working as expected
测试:
> get("So", env = dict_g2e) # ran without the set_dict <- function() {...} part
[1] "Sun"
dict_e2g
做同样的事情。是否有更快的&amp;更短的方法吗?get("So", env = dict_g2e)
更好的命令?是否存在针对g2e <- function(wd) {get(wd, envir = dict_g2e)}
@Roland和@alexis_laz的评论后编辑:
df_dict <- function() {
df <- data.frame(german = c("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"),
english = c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"),
stringsAsFactors = F)
return(df)
}
df <- df_dict()
df_g2e <- function(wd) {
df$english[which(df$german == wd)]
}
微基准:
print(summary(microbenchmark::microbenchmark(
g2e("So"),
df_g2e("So"),
times = 1000L, unit = "us")))
}
结果:
expr min lq mean median uq max neval
g2e("So") 1.520 2.280 2.434178 2.281 2.661 17.106 1000
df_g2e("So") 12.545 15.205 16.368450 15.966 16.726 55.500 1000
答案 0 :(得分:2)
您可以使用闭包:
dict <- function() { # Delete this line and ...
dict_g2e <- new.env(hash = TRUE, size = 7)
from <- c("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa")
to <- c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat")
for (i in 1:19) {
assign(x = from[i], value = to[i], envir = dict_g2e)
}
function(from) {
dict_g2e[[from]]
}
}
wdays1 <- dict()
wdays1("So")
#[1] "Sun"
然而,矢量子集更快:
wdays2 <- setNames(c("Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"),
c("So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"))
在全球环境中定义环境的速度更快:
wdays3 <- list2env(as.list(wdays2), hash = TRUE)
library(microbenchmark)
microbenchmark(for (i in seq_len(1e3)) wdays1("Mi"),
for (i in seq_len(1e3)) wdays2[["Mi"]],
for (i in seq_len(1e3)) wdays3[["Mi"]])
#Unit: microseconds
# expr min lq mean median uq max neval cld
# for (i in seq_len(1000)) wdays1("Mi") 434.045 488.205 520.6626 507.0265 516.2455 2397.108 100 c
# for (i in seq_len(1000)) wdays2[["Mi"]] 182.324 211.005 214.6720 215.9985 217.9190 239.173 100 b
# for (i in seq_len(1000)) wdays3[["Mi"]] 141.609 164.143 167.1088 168.2410 169.7770 190.007 100 a
然而,矢量方法有一个明显的优势:它是矢量化的。
wdays2[c("So", "Do")]
# So Do
# "Sun" "Thurs"
如果要在两个方向上进行翻译,使用data.frame将是一种自然的方法,但data.frame子集化速度相当慢。您可以使用两个命名向量,每个方向一个。