R: сворачивать дублированные значения в столбце, сохраняя порядок - PullRequest
0 голосов
/ 29 мая 2018

Я уверен, что это очень просто, но просто не могу найти ответ.У меня есть фрейм данных примерно так:

    Id  event
1   1   A
2   1   B
3   1   A
4   1   A
5   2   C
6   2   C
7   2   A

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

    Id  event
1   1   A
2   1   B
3   1   A
4   2   C
5   2   A

Большинство моих поисков заканчиваются использованием функций distinct() или unique(), но это приводит к потере события A в строке 3 для Id 1.

Заранее спасибо!

Ответы [ 5 ]

0 голосов
/ 22 апреля 2019

Я думаю, что функция distinct сможет решить проблему.

dat %>% distinct(Id, event)

0 голосов
/ 30 мая 2018

Базовое решение R с использованием tapply и rle:

x <- tapply(dat$event,dat$Id,function(x) rle(x)$values)
do.call(rbind,Map(data.frame,Id=names(x),event=x))
#     Id event
# 1.1  1     A
# 1.2  1     B
# 1.3  1     A
# 2.1  2     C
# 2.2  2     A
0 голосов
/ 29 мая 2018

Мы можем использовать lead для сравнения каждой строки и filter тех строк, которые отличаются от предыдущих.is.na(lead(Id)) также включает последние строки.

library(dplyr)

dat2 <- dat %>% 
  filter(!(Id == lead(Id) & event == lead(event)) | is.na(lead(Id)))
dat2
#   Id event
# 1  1     A
# 2  1     B
# 3  1     A
# 4  2     C
# 5  2     A

DATA

dat <- read.table(text = "    Id  event
1   1   A
                  2   1   B
                  3   1   A
                  4   1   A
                  5   2   C
                  6   2   C
                  7   2   A",
                  header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 29 мая 2018

Вот решение с data.table:

library("data.table")
dt <- fread(
" Id  event
   1   A
   1   B
   1   A
   1   A
   2   C
   2   C
   2   A")
unique(dt[, r:=rleidv(event), Id])[, -3]
#    Id event
# 1:  1     A
# 2:  1     B
# 3:  1     A
# 4:  2     C
# 5:  2     A

или

dt[, .SD[unique(rleidv(event))], by = Id]

(спасибо за комментарий @ mt1022)

0 голосов
/ 29 мая 2018

Вы можете просто сравнить каждую строку с одной после нее.

df = read.table(text=" Id  event
1   1   A
2   1   B
3   1   A
4   1   A
5   2   C
6   2   C
7   2   A", 
header=TRUE)

df[rowSums(df[-1,] == head(df, -1)) !=2, ]
  Id event
1  1     A
2  1     B
4  1     A
6  2     C
7  2     A
...