通过分隔符将矢量分割成块

时间:2016-05-24 22:44:25

标签: r split

我有以下结构:

timestamp = c(1,2,3,4,5,6,7,8,9,10)
values = c(1337,42,NA,23,67,2,NA,NA,NA,5)
df = data.frame(timestamp,values)

#    timestamp values
# 1          1   1337
# 2          2     42
# 3          3     NA
# 4          4     23
# 5          5     67
# 6          6      2
# 7          7     NA
# 8          8     NA
# 9          9     NA
# 10        10      5

现在我想知道,有多少相干块(在这种情况下为3:[1337,42] [23,67,2]和[5]。也许我甚至可以将它拆分为子数据帧或其他东西像这样?

4 个答案:

答案 0 :(得分:5)

以下是使用data.table执行此操作的方法:

library(data.table)
timestamp = c(1,2,3,4,5,6,7,8,9,10)
values = c(1337,42,NA,23,67,2,NA,NA,NA,5)
dt = data.table(timestamp,values)
dt[, previous:=shift(values)]
res <- dt[!is.na(values) & is.na(previous), .N]
res
# [1] 3 

由于评论中提到了性能,这里是解决方案的基准(在1e5行上):

    Unit: milliseconds
          expr        min        lq      mean     median        max neval
     dt[shift]   3.966346   4.03936   4.90822   4.728635   7.345617    10
 split[cumsum]  15.693565  17.38094  18.79429  17.739346  31.370630    10
           rle  42.375227  42.65068  45.82327  45.326625  51.473468    10
         dplyr 645.156377 655.90239 676.37797 678.966334 711.393856    10

答案 1 :(得分:3)

使用库dplyr,您可以执行以下操作:

library(dplyr)
timestamp = c(1,2,3,4,5,6,7,8,9,10)
values = c(1337,42,NA,23,67,2,NA,NA,NA,5)
df = data.frame(timestamp,values)
df %>%
  mutate(id = cumsum(is.na(values) | is.na(lag(values)))) %>%
  filter(!is.na(values)) %>%
  group_by(id) %>%
  summarise(chunks = paste(values, collapse = ',')) %>%
  select(-id)

输出是:

Source: local data frame [3 x 1]

   chunks
    <chr>
1 1337,42
2 23,67,2
3       5

答案 2 :(得分:3)

您还可以使用rlerleid功能:

library(data.table)
values = c(1337,42,NA,23,67,2,NA,NA,NA,5)
split(values, rleid(is.na(values)))[rle(!is.na(values))$values]
$`1`
[1] 1337   42

$`3`
[1] 23 67  2

$`5`
[1] 5

答案 3 :(得分:3)

正如rawr在评论中建议我使用以下解决方案:

foo <- function( x ){
   idx <- 1 + cumsum( is.na( x ) )
   not.na <- ! is.na( x )
   result <- split( x[not.na], idx[not.na] )
   return(result)
}

原因:

  • 这是第一个解决方案
  • 工作
  • 我理解
  • 它不使用任何包/库。

仍然感谢所有答案!

我会尽可能地回答这个问题(两天之内)。