R语言 删除tibble中的偏移行

50few1ms  于 2023-04-03  发布在  其他
关注(0)|答案(2)|浏览(166)

请注意,数据的顺序和VALUE列与我之前的问题不同。How do I remove offsetting rows in a tibble?问题的可接受答案适用于我提供的数据集,但更改值会导致答案失败。

我正在尝试删除具有偏移值的行。

library(dplyr)
a <- c(1, 1, 1, 1, 2, 2, 2, 2,2,2)
b <- c("a", "b", "b", "b", "c", "c","c", "d", "d", "d")
d <- c(10, 10, -10, 50, 20, -20, 60, 30, -30, 70)
o <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J")
df <- tibble(ID = a, SEQ = b, VALUE = d, OTHER = o)

生成此按ID和SEQ分组的有序表。

> df
# A tibble: 10 x 4
      ID   SEQ VALUE OTHER
   <dbl> <chr> <dbl> <chr>
 1     1     a    10     A
 2     1     b   -10     B
 3     1     b    10     C
 4     1     b    50     D
 5     2     c   -20     E
 6     2     c    20     F
 7     2     c    60     G
 8     2     d   -30     H
 9     2     d    30     I
10     2     d    70     J

我想删除行对(2,3),(5,6),(8,9),因为VALUE对匹配的前一行中的VALUE求反。
我希望结果表为

> df2
# A tibble: 4 x 4
     ID   SEQ VALUE OTHER
  <dbl> <chr> <dbl> <chr>
1     1     a    10     A
2     1     b    50     D
3     2     c    60     G
4     2     d    70     J

我知道我不能使用group_by %>% summarize,因为我需要保留OTHER中的值。我看过dplyr::lag()函数,但我不知道它有什么帮助。我相信我可以用某种类型的for each循环遍历表,并生成一个逻辑向量,可以用来删除行,但我希望有一个更优雅的解决方案。

bqucvtff

bqucvtff1#

这是另一种解决方案,它不像公认的答案那样有任何假设:
1-数据也基于VALUE排序
2-每当cumsum的差值为负时,这意味着与前一行相比,该值已被取反。
3-如果差值为负,则这些行在同一组中(根据提供的有序数据,这在一定程度上是可以接受的)。
更普遍的答案是:

df %>% arrange(ID,SEQ,VALUE) %>%  group_by(ID, SEQ) %>% 
              mutate(helper = VALUE + lag(VALUE, default = -999)) %>% 
              filter(!(helper==0 | lead(helper, default = -999)==0)) %>% select(-helper))
## # A tibble: 4 x 4
## # Groups:   ID, SEQ [4]
##      ID   SEQ VALUE OTHER
##   <dbl> <chr> <dbl> <chr>
## 1     1     a    10     A
## 2     1     b    50     D
## 3     2     c    60     G
## 4     2     d    70     J
qhhrdooz

qhhrdooz2#

除非我完全误解了你的问题,这能起作用吗?

idx <- which(diff(cumsum(df$VALUE)) < 0);
df[-c(idx, idx + 1), ];
## A tibble: 4 x 4
#     ID   SEQ VALUE OTHER
#  <dbl> <chr> <dbl> <chr>
#1     1     a    10     A
#2     1     b    50     D
#3     2     c    60     G
#4     2     d    70     J

相关问题