我有以下结构:
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]。也许我甚至可以将它拆分为子数据帧或其他东西像这样?
答案 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)
您还可以使用rle
和rleid
功能:
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)
}
原因:
仍然感谢所有答案!
我会尽可能地回答这个问题(两天之内)。