[英]Split vector into chunks by delimiter
I have the following structure: 我有以下结构:
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
Now I want to know, how many coherent chunks there are (in this case 3: [1337,42] [23,67,2] and [5]. Maybe I can even split it to sub data frames or something like this? 现在我想知道,有多少连贯的块(在这种情况下为3:[1337,42] [23,67,2]和[5]。也许我甚至可以将它分成子数据帧或类似的东西?
Here is a way to do this with data.table
: 以下是使用data.table
执行此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
As performance was mentioned in the comment, here is the benchmark of solutions (on 1e5 rows): 由于评论中提到了性能,这里是解决方案的基准(在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
Using library dplyr
, you can do something like this: 使用库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)
Output is: 输出是:
Source: local data frame [3 x 1]
chunks
<chr>
1 1337,42
2 23,67,2
3 5
You can also use rle
and rleid
function: 您还可以使用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
As rawr suggested in the comments i am using the following solution: 正如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)
}
Reasons: 原因:
Still thanks for all answers! 仍然感谢所有的答案!
I will mark this as answered as soo as i can (in two days). 我会尽可能地回答这个问题(两天之内)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.