【问题标题】:Why there appear three NA's at the end?为什么最后会出现三个NA?
【发布时间】:2019-07-31 17:45:16
【问题描述】:

我试图为两个任意长度的向量编写一个interleave() 函数。

对于等长向量, 我在internet找到:

.interleave <- function(vec1, vec2) {
  # cuts away longer
  res <- rbind(vec1, vec2)
  attributes(res) <- NULL
  res
}
# c(rbind(vec1, vec2)) is shorter code, but 
# is 3x slower according to the blog in the link

所以对于任意长度,我想,我先测量长度,然后附加较长向量的其余部分。

interleave <- function(vec1, vec2) {
  vec1_len <- length(vec1)
  vec2_len <- length(vec2)
  min_len  <- min(vec1_len, vec2_len)
  if (vec1_len == vec2_len) {
    .interleave(vec1, vec2)
  } else {
    c(.interleave(vec1[1:min_len], vec2[1:min_len]),
      if (vec1_len > vec2_len) { 
        vec1[min_len+1:vec1_len]
      } else {
        vec2[min_len+1:vec2_len]
      })  
  }
} # strangely 3 NA's at end if unequal length

但现在奇怪的事情来了:

interleave(c(1, 2, 3), c(4, 5, 6, 7, 8, 9))
## [1]  1  4  2  5  3  6  7  8  9 NA NA NA

interleave(c(1, 2, 3), c(4, 5, 6))
## [1] 1 4 2 5 3 6 

interleave(c(1, 2, 3), c(4, 5))
## [1]  1  4  2  5  3 NA NA

interleave(c(1, 2, 3), c(4, 5, 6, 7, 8, 9, 10, 11))
## [1]  1  4  2  5  3  6  7  8  9 10 11 NA NA NA
interleave(c(1, 2, 3, 4, 5, 6), c( 7, 8, 9, 10, 11))
## [1]  1  7  2  8  3  9  4 10  5 11  6 NA NA NA NA NA

NAs 来自哪里? 备注:我看到附上NAs的数量的模式 是较短向量中元素的数量...

如何生成没有NAs的版本?

解决方案

对不起,我自己发现的。 问题是剩余向量的子集。 我忘记了一些括号。

interleave <- function(vec1, vec2) {
  vec1_len <- length(vec1)
  vec2_len <- length(vec2)
  min_len  <- min(vec1_len, vec2_len)
  if (vec1_len == vec2_len) {
    .interleave(vec1, vec2)
  } else {
    c(.interleave(vec1[1:min_len], vec2[1:min_len]),
      if (vec1_len > vec2_len) { 
        vec1[(min_len+1):vec1_len] # parantheses!
      } else {
        vec2[(min_len+1):vec2_len] # parantheses!
      })  
  }
} # no NA's any more!

略短

interleave <- function(vec1, vec2) {
  vec1_len <- length(vec1)
  vec2_len <- length(vec2)
  min_len  <- min(vec1_len, vec2_len)
  if (vec1_len == vec2_len) {
    .interleave(vec1, vec2)
  } else {
    c(.interleave(vec1[1:min_len], vec2[1:min_len]),
      if (vec1_len > vec2_len) {
        vec1[(min_len+1):vec1_len]
      } else {
        vec2[(min_len+1):vec2_len]
      })
  }
}

【问题讨论】:

    标签: r


    【解决方案1】:

    一般功能:

    interleave <- function(...) {
        l <- list(...)
        len <- max(lengths(l))
        l <- lapply(l, function(x) `length<-`(x, len))
        res <- na.omit(c(do.call(rbind, l)))
        attributes(res) <- NULL
        res
    }
    
    interleave(1:9, seq(10,40,10), seq(100,500,100))
    #[1]   1  10 100   2  20 200   3  30 300   4  40 400   5 500   6   7   8   9
    

    也泛化Interleave lists in R

    interleave <- function(...) {
        l <- list(...)
        idx <- order(unlist(lapply(l, function(x) seq_along(x))))
        unlist(l)[idx]
    }
    

    【讨论】:

    • 谢谢。这种我也是。但我试图避免列表。因为 R 中的列表非常慢。我的interleave() 只是我想写的strsplit() 等效项的辅助函数,因为strsplit() 在内部使用列表,因此非常慢。我正在尝试编写一种主要使用substr()gregexpr() 来拆分字符串的方法。因为这要快得多。我知道 tidyverse 中已经存在这样的功能。但我想自己写一个来学习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-29
    相关资源
    最近更新 更多