我需要创建一个具有给定模式和长度的向量。我使用此代码有效:
NA_vec<-function(vec_mode, vec_length)
{
vec<-vector(mode=vec_mode, length=vec_length)
vec<-replace(vec, vec==0, NA)
return(vec)
}
a<-NA_vec("numeric", 20)
Run Code Online (Sandbox Code Playgroud)
问题:是否有更快的方法可以做到这一点?
编辑1:
另一个慢版本,但我认为可以在任何模式下使用:
NA_vec5 = function(vec_mode, vec_length)
{
vec<-vector(mode=vec_mode, length=vec_length)
for (i in 1:length(vec))
{
vec[i]<-NA
}
return(vec)
}
Run Code Online (Sandbox Code Playgroud)
基准测试:
n = 1e5
microbenchmark::microbenchmark(
DJJ=NA_vec4("numeric", n),
Gregor = NA_vec3("numeric", n),
G5W = NA_vec2("numeric", n),
OP = NA_vec("numeric", n),
OP_with_for = NA_vec5("numeric", n)
)
Run Code Online (Sandbox Code Playgroud)
基准输出:
Unit: microseconds
expr min lq mean median uq max neval cld
DJJ 269.213 348.7520 489.1965 382.3055 424.9365 10240.310 100 a
Gregor 351.713 430.0685 578.2138 475.4635 542.7665 8784.119 100 a
G5W 1051.979 1207.5065 1588.2552 1271.6510 1364.6125 24294.583 100 b
OP 1537.902 1776.1270 2732.4603 1934.4170 2101.9840 26363.014 100 c
OP_with_for 5772.263 6065.1595 6473.3508 6196.4100 6376.8055 11310.446 100 d
Run Code Online (Sandbox Code Playgroud)
NA直接使用适当的类型:
NA_vec3 = function(mode, length) {
mode = match.arg(mode, choices = c("numeric", "integer", "complex", "logical", "character"))
if (mode == "numeric") return(rep(NA_real_, length))
if (mode == "integer") return(rep(NA_integer_, length))
if (mode == "complex") return(rep(NA_complex_, length))
if (mode == "character") return(rep(NA_character_, length))
rep(NA, length)
}
n = 1e5
microbenchmark::microbenchmark(
Gregor = NA_vec3("numeric", n),
G5W = NA_vec2("numeric", n),
OP = NA_vec("numeric", n)
)
# Unit: microseconds
# expr min lq mean median uq max neval
# Gregor 210.160 224.4410 343.2125 244.5395 271.3385 7749.094 100
# G5W 644.583 670.8525 1280.5191 683.7235 705.5860 11864.828 100
# OP 995.436 1021.7055 2020.2795 1051.8545 1346.6415 12450.877 100
Run Code Online (Sandbox Code Playgroud)
出于历史利益,此答案已删除:
NA_vec2<-function(vec_mode, vec_length) {
vec<-vector(mode=vec_mode, length=vec_length)
vec<-replace(vec, 1:vec_length, NA)
}
Run Code Online (Sandbox Code Playgroud)
作为另一个想法,我也尝试过这样做,但是它甚至比原始版本慢,因此我将其省略。
# slowest yet
NA_vec4 = function(mode, length) {
x = rep(NA, length)
storage.mode(x) = mode
x
}
Run Code Online (Sandbox Code Playgroud)