выберите первое и последнее вхождения значения в данный месяц - PullRequest
2 голосов
/ 19 января 2020

У меня есть набор данных, в котором записываются изменения в группе с определенного идентификатора за определенный месяц. В этом примере в июле идентификатор 5 изменился с группы 2 на группу 1, затем с группы 1 на 2 и так далее. Мне нужно получить только первые и последние изменения, внесенные в этот идентификатор / месяц.

ID  groupTO groupFROM   MONTH
5   2   1   6
5   1   2   7
5   2   1   7
5   3   2   7
5   1   3   7
5   2   1   8
5   1   2   8
5   2   1   8
6   1   2   6
6   3   1   6
6   2   1   7
6   3   2   8
6   1   3   8

В этом случае мне нужны следующие результаты:

ID  groupTO groupFROM   MONTH
5   2   1   6
5   1   2   7
5   1   3   7
5   2   1   8
5   2   1   8
6   1   2   6
6   3   1   6
6   2   1   7
6   3   2   8
6   1   3   8

Если я удалю дубликаты (ID / МЕСЯЦ), я могу получить первый случай, но как мне получить последний?

Ответы [ 4 ]

1 голос
/ 20 января 2020

Вот простой способ сделать это с помощью dplyr;

library(dplyr)

# Create data
dt <- 
  data.frame(Id = c(rep(5, 8), rep(6, 5)), 
             groupTO = c(2, 1, 2, 3, 1, 2, 1, 2, 1, 3, 2, 3, 1),
             groupFROM = c(1, 2, 1, 2, 3, 1, 2, 1, 2, 1, 1, 2, 3),
             MONTH = c(6, 7, 7, 7, 7, 8, 8, 8, 6, 6, 7, 8, 8))

dt %>%
  # Group by ID and month
  group_by(Id, MONTH) %>%
  # Get first and last row
  slice(c(1, n())) %>%
  # To remove cases where first is same as last
  distinct()

# # A tibble: 9 x 4
# # Groups:   Id, MONTH [6]
# Id groupTO groupFROM MONTH
# <dbl>   <dbl>     <dbl> <dbl>
# 5       2         1     6
# 5       1         2     7
# 5       1         3     7
# 5       2         1     8
# 6       1         2     6
# 6       3         1     6
# 6       2         1     7
# 6       3         2     8
# 6       1         3     8
0 голосов
/ 20 января 2020

Базовый путь R с использованием ave, где мы выбираем 1-ю и последнюю строку для каждого ID и MONTH и выбираем строки unique в кадре данных.

unique(subset(df, ave(groupTO == 1, ID, MONTH, FUN = function(x) 
              seq_along(x) %in% c(1, length(x)))))

#   ID groupTO groupFROM MONTH
#1   5       2         1     6
#2   5       1         2     7
#5   5       1         3     7
#6   5       2         1     8
#9   6       1         2     6
#10  6       3         1     6
#11  6       2         1     7
#12  6       3         2     8
#13  6       1         3     8
0 голосов
/ 20 января 2020

Вот базовое решение R с использованием split

dfout <- do.call(rbind,c(make.row.names = F,
                lapply(split(df,df[c("Id","MONTH")],lex.order = T), 
                       function(v) if (nrow(v)==1) v[1,] else v[c(1,nrow(v)),])))

, такое что

> dfout
   Id groupTO groupFROM MONTH
1   5       2         1     6
2   5       1         2     7
3   5       1         3     7
4   5       2         1     8
5   5       2         1     8
6   6       1         2     6
7   6       3         1     6
8   6       2         1     7
9   6       3         2     8
10  6       1         3     8```
0 голосов
/ 20 января 2020

Использование data.table

library(data.table)
unique(setDT(df1)[, .SD[c(1, .N)], .(ID, MONTH)])
#    ID MONTH groupTO groupFROM
#1:  5     6       2         1
#2:  5     7       1         2
#3:  5     7       1         3
#4:  5     8       2         1
#5:  6     6       1         2
#6:  6     6       3         1
#7:  6     7       2         1
#8:  6     8       3         2
#9:  6     8       1         3

данных

df1 <- structure(list(ID = c(5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 
6L, 6L, 6L), groupTO = c(2L, 1L, 2L, 3L, 1L, 2L, 1L, 2L, 1L, 
3L, 2L, 3L, 1L), groupFROM = c(1L, 2L, 1L, 2L, 3L, 1L, 2L, 1L, 
2L, 1L, 1L, 2L, 3L), MONTH = c(6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 
6L, 6L, 7L, 8L, 8L)), class = "data.frame", row.names = c(NA, 
-13L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...