我正在尝试解决最基本的示例并尝试提取以下数据:
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
循环来进行检查,但是正在寻找一种快捷方式。
答案 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.table
为filter
行创建逻辑向量
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))