按组选择每次运行零之前的最后一个非零值

我有以下数据框:

   variable       Date values values2
1         a 2017-01-01      3       1
2         a 2017-01-02      4       2
3         a 2017-01-03      5       1 # non-zero followed by zero
4         a 2017-01-04      0       2
5         a 2017-01-05      0       2
6         a 2017-01-06      0       3
7         b 2017-01-01     10       1
8         b 2017-01-02     11       2
9         b 2017-01-03     12       2
10        b 2017-01-04     13       3
11        b 2017-01-05     14       0
12        b 2017-01-06     15       1
13        c 2017-01-01     45       2
14        c 2017-01-02     50       3 # non-zero followed by zero
15        c 2017-01-03      0       0
16        c 2017-01-04      0       2
17        c 2017-01-05     10       1 # non-zero followed by zero
18        c 2017-01-06      0       1

我想在“值”列中选择非零值后跟零的行:

1 a        2017-01-03      5       1
2 c        2017-01-02     50       3
3 c        2017-01-05     10       1

请注意,一个变量中可能出现多个最后一个非零值。

我的代码不能正常工作,因为每个变量只有最后一个元素:

test_df <- structure(list(variable = c("a","a","b","c","c"),Date = structure(c(17167,17168,17169,17170,17171,17172,17167,17172),class = "Date"),values = c(3,4,5,10,11,12,13,14,15,45,50,0),values2 = c(1,2,1,3,1)),row.names = c(NA,-18L),class = "data.frame",.Names = c("variable","Date","values","values2"))

 test_df %>% 
  group_by(variable=factor(variable)) %>% 
  filter(any(values==0)) %>% 
  filter(values != 0) %>% 
  arrange(Date) %>% 
  slice(n()) %>% 
  ungroup() 

1 a        2017-01-03      5       1
2 c        2017-01-05     10       1
wanghaitao1987 回答:按组选择每次运行零之前的最后一个非零值

这可以帮助您:

library(dplyr)

test_df %>%
  group_by(variable) %>%
  filter(values != 0 & lead(values) == 0)

  variable       Date values values2
1        a 2017-01-03      5       1
2        c 2017-01-02     50       3
3        c 2017-01-05     10       1
,

使用 subset 中的 base R

subset(test_df,head(values,-1) != 0 &  tail(values,-1) == 0)
   variable       Date values values2
3         a 2017-01-03      5       1
14        c 2017-01-02     50       3
17        c 2017-01-05     10       1

如果已分组,只需将其包装在 ave

subset(test_df,ave(values,variable,FUN = function(x) 
     c(head(x,-1)  != 0 & tail(x,-1) == 0,FALSE))> 0)
 variable       Date values values2
3         a 2017-01-03      5       1
14        c 2017-01-02     50       3
17        c 2017-01-05     10       1
,

使用 diff 的另一个基本 R 选项

> subset(
+   test_df,+   ave(values == 0,FUN = function(x) c(diff(x) == 1,FALSE))
+ )
   variable       Date values values2
3         a 2017-01-03      5       1
14        c 2017-01-02     50       3
17        c 2017-01-05     10       1
,

为了完成这里是 data.table 答案 -

library(data.table)
setDT(test_df)[,.SD[values != 0 & shift(values,type = 'lead') == 0],variable]

#   variable       Date values values2
#1:        a 2017-01-03      5       1
#2:        c 2017-01-02     50       3
#3:        c 2017-01-05     10       1
本文链接:https://www.f2er.com/1143.html

大家都在问