【问题标题】:Outputting a vector with repeated values输出具有重复值的向量
【发布时间】:2020-01-14 15:49:12
【问题描述】:

为了保持我的脚本记录干净,我想用 rep() 输出向量输入,而不是链中的重复值。请参阅下面的示例,使用 dput():

v<-c(rep(1,2), rep(2,4), rep(NA,5))
dput(v)
>c(1, 1, 2, 2, 2, 2, NA, NA, NA, NA, NA)
unknown_function(v)
>c(rep(1,2), rep(2,4), rep(NA,5))

当然是微不足道的,但我找不到任何简单的解决方案。请给 unknown_function() 的建议?

【问题讨论】:

  • 基本上,rle(v) 将完成大部分工作。唯一的问题是您的 NA 值。 rle 将它们视为统计学家,这意味着它不会假设它们是相同的值。转换为字符并非总是不损失精度。如果这不是问题(例如,您只有整数值),那么 Gabor 的答案就可以了。

标签: r vector


【解决方案1】:

rle 将计算值和长度,然后我们可以将它们粘贴在一起:

with(rle(format(v)), paste0("c(", toString(paste0("rep(", values, ",", lengths, ")")), ")"))
## [1] "c(rep( 1,2), rep( 2,4), rep(NA,5))"

【讨论】:

    【解决方案2】:

    您可以使用rle 的结构编写一个函数并将其更改为 crunch 也NA 并将其与@g-grothendieck 中的方法结合使用。

    dputRle <- function (x, nmin=3) {
      if (!is.vector(x) && !is.list(x)) 
        stop("'x' must be a vector of an atomic type")
      n <- length(x)
      if (n <= 1L) 
        return(x)
      y <- x[-1L] != x[-n] | is.na(x[-1L]) != is.na(x[-n])
      i <- c(which(y), n)
      lengths = diff(c(0L, i))
      paste0("c(", toString(unlist(sapply(seq(i), function(y) {
        if(lengths[y] <= nmin) {rep(x[i[y]], lengths[y])
        } else {paste0("rep(", x[i[y]], ",", lengths[y], ")")}
      }))), ")")
    }
    
    v <- c(rep(1,2), rep(2,4), rep(NA,5), 1)
    dputRle(v, 1)
    #[1] "c(rep(1,2), rep(2,4), rep(NA,5), 1)"
    dputRle(v)
    #"c(1, 1, rep(2,4), rep(NA,5), 1)"
    
    v <- 1
    dputRle(v)
    #[1] 1
    
    v <- numeric(0)
    dputRle(v)
    #numeric(0)
    

    或替代。

    dputRle2 <- function (x) {
      if (!is.vector(x) && !is.list(x)) 
        stop("'x' must be a vector of an atomic type")
      n <- length(x)
      if (n <= 1L) 
        return(x)
      y <- x[-1L] != x[-n] | is.na(x[-1L]) != is.na(x[-n])
      i <- c(which(y), n)
      paste0("rep(c(", toString(x[i]), "), c(", toString(diff(c(0L, i))), "))")
    }
    
    v <- c(rep(1,2), rep(2,4), rep(NA,5), 1)
    dputRle2(v)
    #[1] "rep(c(1, 2, NA, 1), c(2, 4, 5, 1))"
    

    有一些方法可以将rlecrep 一起使用。以下所有内容都会产生相同的向量。

    c(1, 2, 2, 3, 3, 3)
    c(1, rep(2, 2), rep(3, 3))
    c(1, rep(c(2, 3), c(2, 3)))
    rep(c(1, 2, 3), c(1, 2, 3))
    rep(1:3, 1:3)
    

    【讨论】:

    • 这真是天才。我对第二个版本特别感兴趣。
    猜你喜欢
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    • 2020-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多