Как сохранить только те строки data.frame, если вся группа удовлетворяет условию - PullRequest
0 голосов
/ 16 октября 2018

Я довольно новичок в R, и у меня есть вопрос о том, как сохранить только определенные значения на основе идентификатора и даты.У меня есть (довольно большой) набор данных, который выглядит как в следующем примере:

ID Type Date
1  OUT 2016-06-18
1  OUT 2016-06-18
1  OUT 2016-06-18
1  IN  2016-06-25
1  OUT 2016-06-25
2  IN  2016-07-03
2  OUT 2016-07-03

Мой вопрос сейчас заключается в том, как найти даты, содержащие ТОЛЬКО один из типов (IN или OUT), и удалить их изданные.Однако я хотел бы сохранить дату, если тип является парой (IN и OUT) и если значение идентификатора одинаково.

Есть ли способ сделать это в R?

Ответы [ 3 ]

0 голосов
/ 16 октября 2018

Если я правильно понял ваше требование, вот простой способ использования пакета dplyr -

df %>%
  group_by(ID, Date) %>%
  filter(n_distinct(Type) > 1)

# A tibble: 4 x 3
# Groups:   ID, Date [2]
     ID Type  Date      
  <int> <chr> <chr>     
1     1 IN    2016-06-25
2     1 OUT   2016-06-25
3     2 IN    2016-07-03
4     2 OUT   2016-07-03

Другой способ использования ave() из базы R -

df[with(df, ave(Type, ID, Date, FUN = function(x) length(unique(x)))) == 2, ]

  ID Type       Date
4  1   IN 2016-06-25
5  1  OUT 2016-06-25
6  2   IN 2016-07-03
7  2  OUT 2016-07-03
0 голосов
/ 27 декабря 2018

Для полноты картины приведены также некоторые решения :

library(data.table)

setDT(df)[, if (uniqueN(Type) > 1) .SD, by = .(ID, Date)]
   ID       Date Type
1:  1 2016-06-25   IN
2:  1 2016-06-25  OUT
3:  2 2016-07-03   IN
4:  2 2016-07-03  OUT

Внутри каждого ID, Date группируются только те подмножества df, для которых существует более одного отдельного Type.


Это также можно записать как:

setDT(df)[, .SD[uniqueN(Type) > 1], by = .(ID, Date)]

Существует также вариант, который находит комбинации ID и Date, которые удовлетворяют требованию и подмножествам df, путем объединения:

setDT(df)[df[, uniqueN(Type), by = .(ID, Date)][V1 > 1], on = .(ID, Date), .SD]
   ID Type       Date
1:  1   IN 2016-06-25
2:  1  OUT 2016-06-25
3:  2   IN 2016-07-03
4:  2  OUT 2016-07-03

данных

df <-readr::read_delim(
"ID Type Date
1  OUT 2016-06-18
1  OUT 2016-06-18
1  OUT 2016-06-18
1  IN  2016-06-25
1  OUT 2016-06-25
2  IN  2016-07-03
2  OUT 2016-07-03", 
delim = " ", trim_ws = TRUE)
0 голосов
/ 16 октября 2018

Вот способ сделать это с dplyr.Это ищет все ID + Date комбинации, которые имеют как минимум один из каждого входа и выхода.

has_both <- df1 %>%
  count(ID, Date, Type) %>%  # How many rows with each combo ID / Date / Type
  count(ID, Date) %>% # How many rows appear for each ID / Date
  filter(nn == 2) %>% # Only keep where 2 types (IN and OUT, presumably)
  left_join(df1)  %>% # Bring back matching original data

Выход

has_both
# A tibble: 4 x 4
     ID Date          nn Type 
  <int> <chr>      <int> <chr>
1     1 2016-06-25     2 IN   
2     1 2016-06-25     2 OUT  
3     2 2016-07-03     2 IN   
4     2 2016-07-03     2 OUT 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...