通过值解构向量

时间:2018-11-24 14:58:15

标签: r

给出部分排序的向量:

A <- c(1,1,1,1,1,0,0,0,0,0,2,2,2,2,2,-1,-1,-1,-1,-1)

目的是将该向量解构为一个表格,以显示这些表格的不同值和范围:

 start end value
 1     5       1
 6     10      0
 11    15      2
 16    20     -1

我尝试使用diff函数,但似乎找不到找到将值聚集到所需范围内的好方法。

2 个答案:

答案 0 :(得分:3)

使用rle()(行程编码)

A <- c(1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
      -1, -1, -1, -1, -1, 1, 1, 1, 0, 0, 0, 0)
rled <- as.data.frame(unclass(rle(A)))

rled$end <- cumsum(rled$lengths)
rled$start <- rled$end - rled$lengths + 1

rled[, c("start", "end", "values")]


#   start end values
# 1     1   5      1
# 2     6  10      0
# 3    11  15      2
# 4    16  20     -1
# 5    21  23      1
# 6    24  27      0

答案 1 :(得分:2)

我们可以使用rleid中的data.table。我们遍历每个唯一编号,找到它在原始序列中的第一个和最后一个出现,然后将其转换为data.frame。

library(data.table) 

indx <- rleid(A)
new_dat <- data.frame(t(sapply(unique(indx), function(x) {
                           val <- which(indx == x)
                          c(start = min(val), stop = max(val))
})))

transform(new_dat, value = A[new_dat$start])


#  X1 X2 value
#1  1  5     1
#2  6 10     0
#3 11 15     2
#4 16 20    -1

当数字重复时

A <- c(1,1,1,1,1,0,0,0,0,0,2,2,2,2,2,-1,-1,-1,-1,-1, 1, 1, 1)

indx <- rleid(A)
new_dat <- data.frame(t(sapply(unique(indx), function(x) {
                          val <- which(indx == x)
                         c(start = min(val), stop = max(val))
})))

transform(new_dat, value = A[new_dat$start])


#  start stop value
#1     1    5     1
#2     6   10     0
#3    11   15     2
#4    16   20    -1
#5    21   23     1

@Henrik建议的一种更简洁的data.table方式

library(data.table)
data.table(A)[ , .(from = .I[1], to = .I[.N], val = A[1]), by = rleid(A)][,-1]


#   from to val
#1:    1  5   1
#2:    6 10   0
#3:   11 15   2
#4:   16 20  -1
#5:   21 23   1