忽略第二个或多个连续的0

时间:2019-01-11 09:27:27

标签: r dataframe

我正在尝试解决最基本的示例并尝试提取以下数据:

count   SN  data.stamp 
1   00601   2018-07-26 13:38:39       
0   00601   2018-11-05 23:00:09       
0   00601   2018-11-05 23:00:16        
4   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05        
5   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05
0   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05

预期输出:

count   SN  data.stamp 
1   00601   2018-07-26 13:38:39       
0   00601   2018-11-05 23:00:09       
4   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05        
5   00601   2018-11-12 23:00:05        
0   00601   2018-12-12 23:00:05

我只考虑具有0值的单个计数。如果0个值有多个计数,则应该只考虑第一个值,而忽略其余0个计数。

基本上,我只是在寻找第一个零值,然后是非零值。

我尝试使用rle,但是我想从data.frame中提取数据。 rle可以为我提供有关值和长度的信息。我可以编写for循环来进行检查,但是正在寻找一种快捷方式。

2 个答案:

答案 0 :(得分:5)

在基数R中,您可以对data.frame进行子集化,以仅获取count与0不同或count为0但上一行与零不同的行:

df[df$count!=0 | (df$count==0 & c(TRUE, head(df$count, -1)!=0)), ]
# (or: subset(df, count!=0 | (count==0 & c(TRUE, head(count, -1)!=0))))

#  count  SN          data.stamp
#1     1 601 2018-07-26 13:38:39
#2     0 601 2018-11-05 23:00:09
#4     4 601 2018-11-12 23:00:05
#5     0 601 2018-12-12 23:00:05
#6     5 601 2018-11-12 23:00:05
#7     0 601 2018-12-12 23:00:05

答案 1 :(得分:2)

我们可以使用rleid中的data.tablefilter行创建逻辑向量

library(dplyr)
df1 %>%
   filter(!duplicated(cbind(data.table::rleid(count), SN)))

更准确地说,rleid可以应用于逻辑矢量

df1 %>% 
  filter(!duplicated(cbind(rleid(count== 0), SN)))

rleid检查相邻元素是否相似,当不等式存在时,它会增加由1创建的ID。即

v1 <- c(1, 0, 0, 5, 4, 5, 5)
rleid(v1)
#[1] 1 2 2 3 4 5 5

现在,所有相邻的重复元素都被赋予相同的ID。如果我们特定于将“ 0”识别为重复项

rleid(v1 == 0)
#[1] 1 2 2 3 3 3 3

这里只有两个值,即TRUE/FALSE

v1 == 0
#[1] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE

duplicated包装会返回索引上的逻辑索引


如果我们需要base R解决方案,可以使用rle完成。用values复制lengths来创建序列,并像以前一样用duplicated换行来获得逻辑向量

i1 <- with(rle(!df1$count), rep(seq_along(values), lengths))
i2 <- !duplicated(cbind(i1, df1$SN))
df1[i2, ]
#  count  SN          data.stamp
#1     1 601 2018-07-26 13:38:39
#2     0 601 2018-11-05 23:00:09
#4     4 601 2018-11-12 23:00:05
#5     0 601 2018-12-12 23:00:05
#6     5 601 2018-11-12 23:00:05
#7     0 601 2018-12-12 23:00:05

数据

df1 <- structure(list(count = c(1L, 0L, 0L, 4L, 0L, 5L, 0L, 0L, 0L), 
    SN = c(601L, 601L, 601L, 601L, 601L, 601L, 601L, 601L, 601L
    ), data.stamp = c("2018-07-26 13:38:39", "2018-11-05 23:00:09", 
    "2018-11-05 23:00:16", "2018-11-12 23:00:05", "2018-12-12 23:00:05", 
    "2018-11-12 23:00:05", "2018-12-12 23:00:05", "2018-11-12 23:00:05", 
    "2018-12-12 23:00:05")), class = "data.frame", row.names = c(NA, 
-9L))