Удаление смещенных строк в тибле
Обратите внимание, что порядок данных и столбец VALUE отличаются от моего предыдущего вопроса. Как удалить смещенные строки в таблице? Принятый ответ на вопрос работает для предоставленного мною набора данных, однако изменение значений приводит к сбою ответа.
Я пытаюсь удалить строки, имеющие значения смещения.
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
, потому что мне нужно сохранить значение, которое находится в ДРУГОЙ. Я посмотрел на dplyr::lag()
функционировать, но я не понимаю, как это может помочь. Я считаю, что я мог бы перебрать таблицу с каким-то типом for each
цикл и генерировать логический вектор, который можно использовать для удаления строк, но я надеялся на более элегантное решение.
2 ответа
Если я полностью не понял ваш вопрос, это делает работу?
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
Это еще одно решение, которое не имеет никаких предположений в отличие от принятого ответа, который предполагает:
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