有没有更快的方法来创建具有给定模式和长度且仅用NA值填充的向量

vas*_*111 1 r vector

我需要创建一个具有给定模式和长度的向量。我使用此代码有效:

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)

Gre*_*gor 6

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)