Условная фильтрация с использованием grepl и относительной позиции строки в группе - PullRequest
0 голосов
/ 11 ноября 2018

У меня есть набор данных, подобный следующему:

Journal_ref <- c("1111","2222","2222","2222","3333","3333","4444","4444")
Journal_type <- c("Adj","Rev","Adj","Rev","Rev","Rev","Adj","Adj")
Journal_value <- c(90,10000,12000,80,9000,500,65,2500)
Dataset <- data.frame(Journal_ref,Journal_type,Journal_value)

Для каждой группы Journal_ref, которую я ищу, чтобы отфильтровать / выбрать строки на основе следующих условий:

  • Если " Adj " включено в Journal_type, отфильтруйте / выберите, чтобы вернуть последнюю строку " Adj " в группе Journal_ref, и
  • Если « Adj » не включено в Journal_type, отфильтруйте / выберите, чтобы вернуть последнее « Rev » в группе Journal_ref

Исходя из приведенного выше примера, необходим конечный результат:

Journal_ref Journal_type Journal_value
1111        Adj                    90
2222        Adj                 12000
3333        Rev                   500
4444        Adj                  2500

Я пытался использовать различные комбинации group_by, filter, if, ifelse, grepl, select и slice, но безуспешно.

Буду признателен за любую помощь, особенно с использованием dplyr.

Ответы [ 3 ]

0 голосов
/ 11 ноября 2018

A dplyr способ сделать это следующим образом.

library(dplyr)

Dataset %>%
  group_by(Journal_ref) %>%
  mutate(Adj = any(Journal_type == "Adj"),
         i = ifelse(Adj, last(which(Journal_type == "Adj")), last(which(Journal_type == "Rev")))) %>%
  filter(row_number() == i) %>%
  select(-Adj, -i)
## A tibble: 4 x 3
## Groups:   Journal_ref [4]
#  Journal_ref Journal_type Journal_value
#  <fct>       <fct>                <dbl>
#1 1111        Adj                     90
#2 2222        Adj                  12000
#3 3333        Rev                    500
#4 4444        Adj                   2500
0 голосов
/ 11 ноября 2018

Другое возможное решение:

Dataset %>% 
  group_by(Journal_ref) %>% 
  filter(Journal_type == c("Rev","Adj")[1 + any(Journal_type == "Adj")]) %>% 
  slice(n())

, что дает:

# A tibble: 4 x 3
# Groups:   Journal_ref [4]
  Journal_ref Journal_type Journal_value
  <fct>       <fct>                <dbl>
1 1111        Adj                     90
2 2222        Adj                  12000
3 3333        Rev                    500
4 4444        Adj                   2500

Что это делает:

  • Вы группируете по Journal_ref
  • Затем вы фильтруете Journal_type только для Adj, когда присутствует, и Rev, когда в группе нет Adj. Использование c("Rev","Adj")[1 + any(Journal_type == "Adj")] дает вам Adj, когда в группе есть хотя бы один, и Rev, когда в группе нет Adj.
  • Наконец, используйте slice(n()) tot, чтобы выбрать последний ряд каждой группы.

Вы также можете сделать это с if_else:

Dataset %>% 
  group_by(Journal_ref) %>% 
  filter(Journal_type == if_else(any(Journal_type == "Adj"), "Adj", "Rev")) %>% 
  slice(n())
0 голосов
/ 11 ноября 2018

Попробуйте это:

library(dplyr)

Dataset %>%
  group_by(Journal_ref, Journal_type) %>%
  summarise(Journal_value = last(Journal_value)) %>%
  ungroup() %>% group_by(Journal_ref) %>%
  filter(!(n() > 1 & Journal_type == "Rev"))

Выход:

  Journal_ref Journal_type Journal_value
  <fct>       <fct>                <dbl>
1 1111        Adj                     90
2 2222        Adj                  12000
3 3333        Rev                    500
4 4444        Adj                   2500
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...