提取数据集中的第一个和最后一个位置

时间:2016-03-17 19:58:03

标签: r dplyr

我有这个数据集,我试图转换以获得"来自"和"到"通过测试的特定数据点分组中的位置。

以下是数据的外观:

pos <- seq(from = 10, to = 100, by = 10)
test <- c(1, 1, 1, 0, 0, 0, 1, 1, 1, 0)
df <- data.frame(pos, test)

所以你可以看到10,20和30位置以及70,80和90通过了测试(b / c测试= 1),但其余的点都没有通过。我正在寻找的答案是一个类似于&#34;答案&#34;的数据框。以下代码中的数据框:

peaknum <- c(1, 2)
from <- c(10, 70)
to <- c(30, 90)
answer <- data.frame(peaknum, from, to)

有关如何转换数据集的任何建议?我很难过。

谢谢, 史蒂夫

2 个答案:

答案 0 :(得分:5)

我们可以使用data.table。使用rleid功能根据相同的相邻值&#39; test&#39;创建游程长度组ID(&#39; peaknum&#39;)。使用&#39; peaknum&#39;作为分组变量,我们得到了“分钟”。和&#39; max&#39; &#39; pos&#39;同时指定&#39; i&#39; as&#39; test == 1&#39;分组行。如果需要,可以使用“峰值数据”。值可以更改为序列(&#39; seq_len(.N)`)。

library(data.table)
setDT(df)[, peaknum:= rleid(test)][test==1, 
   list(from=min(pos), to=max(pos)) ,peaknum][, peaknum:= seq_len(.N)]
#   peaknum from to
#1:       1   10 30
#2:       2   70 90

答案 1 :(得分:3)

我们可以使用dplyr来完成它,虽然分离节点有点难看:

library(dplyr)
df %>% group_by(peaknum = rep(seq(rle(test)[['lengths']]), rle(test)[['lengths']])) %>% 
  filter(test == 1) %>% 
  summarise(from = min(pos), 
            to = max(pos)) %>%
  mutate(peaknum = seq_along(peaknum))

# Source: local data frame [2 x 3]

#   peaknum  from    to
#     (int) (dbl) (dbl)
# 1       1    10    30
# 2       2    70    90

它的作用:

  • 第一个group_by使用rle添加一个列,该列是test中重复数字的序列,稍后将其分组为summarise;
  • filter将行向下排列到test1
  • 的行
  • summarise折叠群组并为每个群组添加maxmin
  • 最后mutate清除了peaknum
  • 的编号