Вывод вектора с повторяющимися значениями - PullRequest
2 голосов
/ 13 января 2020

Чтобы сохранить чистоту записей моего скрипта, я хотел бы выводить векторные входы с 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 (), пожалуйста?

Ответы [ 2 ]

5 голосов
/ 13 января 2020

rle вычислит значения и длины, и из этого мы можем вставить их вместе:

with(rle(format(v)), paste0("c(", toString(paste0("rep(", values, ",", lengths, ")")), ")"))
## [1] "c(rep( 1,2), rep( 2,4), rep(NA,5))"
1 голос
/ 13 января 2020

Вы можете написать функцию, используя структуру rle и изменить ее на хруст также 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))"

Есть несколько способов использования rle с c и rep. Все последующее будет иметь одинаковый вектор.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...